-
Notifications
You must be signed in to change notification settings - Fork 22.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add reference for errors related to classes (#34791)
- Loading branch information
Showing
8 changed files
with
599 additions
and
0 deletions.
There are no files selected for viewing
112 changes: 112 additions & 0 deletions
112
files/en-us/web/javascript/reference/errors/bad_super_call/index.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
--- | ||
title: "SyntaxError: super() is only valid in derived class constructors" | ||
slug: Web/JavaScript/Reference/Errors/Bad_super_call | ||
page-type: javascript-error | ||
--- | ||
|
||
{{jsSidebar("Errors")}} | ||
|
||
The JavaScript exception "super() is only valid in derived class constructors" occurs when the {{jsxref("Operators/super", "super()")}} call is used somewhere that's not the body of a [constructor](/en-US/docs/Web/JavaScript/Reference/Classes/constructor) in a class with [`extends`](/en-US/docs/Web/JavaScript/Reference/Classes/extends) keyword. | ||
|
||
## Message | ||
|
||
```plain | ||
SyntaxError: 'super' keyword unexpected here (V8-based) | ||
SyntaxError: super() is only valid in derived class constructors (Firefox) | ||
SyntaxError: super is not valid in this context. (Safari) | ||
``` | ||
|
||
## Error type | ||
|
||
{{jsxref("SyntaxError")}} | ||
|
||
## What went wrong? | ||
|
||
The `super()` call is used to invoke the base constructor of a derived class, so the base class can initialize the {{jsxref("Operators/this", "this")}} object. Using it anywhere else doesn't make sense. | ||
|
||
`super()` can also be defined in an arrow function that's nested within the constructor. However, it cannot be defined in any other kind of function. | ||
|
||
## Examples | ||
|
||
### Invalid cases | ||
|
||
You cannot call `super()` if the class has no `extends`, because there's no base class to call: | ||
|
||
```js example-bad | ||
class Base { | ||
constructor() { | ||
super(); | ||
} | ||
} | ||
``` | ||
|
||
You cannot call `super()` in a class method, even if that method is called from the constructor: | ||
|
||
```js example-ba | ||
class Base {} | ||
|
||
class Derived extends Base { | ||
constructor() { | ||
this.init(); | ||
} | ||
|
||
init() { | ||
super(); | ||
} | ||
} | ||
``` | ||
|
||
You cannot call `super()` in a function, even if the function is used as a constructor: | ||
|
||
```js example-bad | ||
function Base(x) { | ||
this.x = x; | ||
} | ||
|
||
function Derived() { | ||
super(1); | ||
} | ||
|
||
Object.setPrototypeOf(Derived.prototype, Base.prototype); | ||
Object.setPrototypeOf(Derived, Base); | ||
``` | ||
|
||
### Valid cases | ||
|
||
You can call `super()` before calling any other method in the constructor: | ||
|
||
```js example-good | ||
class Base {} | ||
|
||
class Derived extends Base { | ||
constructor() { | ||
super(); | ||
this.init(); | ||
} | ||
|
||
init() { | ||
// ... | ||
} | ||
} | ||
``` | ||
|
||
You can call `super()` in an arrow function that's nested within the constructor: | ||
|
||
```js example-good | ||
class Base {} | ||
|
||
class Derived extends Base { | ||
constructor() { | ||
const init = () => { | ||
super(); | ||
}; | ||
|
||
init(); | ||
} | ||
} | ||
``` | ||
|
||
## See also | ||
|
||
- [Classes](/en-US/docs/Web/JavaScript/Reference/Classes) | ||
- {{jsxref("Operators/super", "super")}} |
97 changes: 97 additions & 0 deletions
97
files/en-us/web/javascript/reference/errors/bad_super_prop/index.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
--- | ||
title: "SyntaxError: use of super property/member accesses only valid within methods or eval code within methods" | ||
slug: Web/JavaScript/Reference/Errors/Bad_super_prop | ||
page-type: javascript-error | ||
--- | ||
|
||
{{jsSidebar("Errors")}} | ||
|
||
The JavaScript exception "use of super property/member accesses only valid within methods or eval code within methods" occurs when the {{jsxref("Operators/super", "super.x")}} or `super[x]` syntax is used outside of a [method](/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions). | ||
|
||
## Message | ||
|
||
```plain | ||
SyntaxError: 'super' keyword unexpected here (V8-based) | ||
SyntaxError: use of super property accesses only valid within methods or eval code within methods (Firefox) | ||
SyntaxError: super is not valid in this context. (Safari) | ||
``` | ||
|
||
## Error type | ||
|
||
{{jsxref("SyntaxError")}} | ||
|
||
## What went wrong? | ||
|
||
The `super.x` syntax is used to access properties on the prototype of the current object. It can be used in methods of both [object literals](/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer) and [classes](/en-US/docs/Web/JavaScript/Reference/Classes), [field initializers](/en-US/docs/Web/JavaScript/Reference/Classes/Public_class_fields), and [static initialization blocks](/en-US/docs/Web/JavaScript/Reference/Classes/Static_initialization_blocks), but not in other contexts. | ||
|
||
## Examples | ||
|
||
### Invalid cases | ||
|
||
You can't use `super.x` outside of a method in an object: | ||
|
||
```js example-bad | ||
const obj = { | ||
__proto__: { x: 1 }, | ||
x: super.x, // SyntaxError | ||
}; | ||
``` | ||
|
||
You can't use `super.x` in a function, even if that function has the effect of being a method: | ||
|
||
```js example-bad | ||
function getX() { | ||
return super.x; // SyntaxError | ||
} | ||
|
||
const obj = { | ||
getX, | ||
getX2: function () { | ||
return super.x; // SyntaxError | ||
}, | ||
}; | ||
|
||
class Derived extends Base { | ||
getX = () => super.x; | ||
} | ||
``` | ||
|
||
### Valid cases | ||
|
||
You can use `super.x` in a method: | ||
|
||
```js example-good | ||
class Base { | ||
x = 1; | ||
} | ||
|
||
class Derived extends Base { | ||
getX() { | ||
return super.x; | ||
} | ||
} | ||
``` | ||
|
||
You can use `super.x` in a field initializer: | ||
|
||
```js example-good | ||
class Derived extends Base { | ||
x = super.x; | ||
} | ||
``` | ||
|
||
You can use `super.x` in object methods too: | ||
|
||
```js example-good | ||
const obj = { | ||
__proto__: { x: 1 }, | ||
getX() { | ||
return super.x; | ||
}, | ||
}; | ||
``` | ||
|
||
## See also | ||
|
||
- [Classes](/en-US/docs/Web/JavaScript/Reference/Classes) | ||
- {{jsxref("Operators/super", "super")}} |
56 changes: 56 additions & 0 deletions
56
files/en-us/web/javascript/reference/errors/builtin_ctor_no_new/index.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
--- | ||
title: "TypeError: calling a builtin X constructor without new is forbidden" | ||
slug: Web/JavaScript/Reference/Errors/Builtin_ctor_no_new | ||
page-type: javascript-error | ||
--- | ||
|
||
{{jsSidebar("Errors")}} | ||
|
||
The JavaScript exception "calling a builtin X constructor without new is forbidden" occurs when you try to call a builtin constructor without using the {{jsxref("Operators/new", "new")}} keyword. All modern constructors, such as {{jsxref("Promise")}} and {{jsxref("Map")}}, must be called with `new`. | ||
|
||
## Message | ||
|
||
```plain | ||
TypeError: Constructor X requires 'new' (V8-based) | ||
TypeError: Promise constructor cannot be invoked without 'new' (V8-based) | ||
TypeError: calling a builtin X constructor without new is forbidden (Firefox) | ||
TypeError: calling X constructor without new is invalid (Safari) | ||
``` | ||
|
||
## Error type | ||
|
||
{{jsxref("TypeError")}} | ||
|
||
## What went wrong? | ||
|
||
In JavaScript, _calling_ a function without `new` and _constructing_ a function with `new` are two distinct operations, and functions can behave differently depending on how they are called. | ||
|
||
Apart from the following legacy constructors, all modern constructors must be called with `new`: | ||
|
||
- {{jsxref("Object/Object", "Object()")}} | ||
- {{jsxref("Function/Function", "Function()")}} (and its subclasses) | ||
- {{jsxref("Error/Error", "Error()")}} (and its subclasses) | ||
- {{jsxref("RegExp/RegExp", "RegExp()")}} | ||
- {{jsxref("Array/Array", "Array()")}} | ||
|
||
Some other constructors, such as {{jsxref("Date/Date", "Date()")}}, and primitive wrappers, such as {{jsxref("String/String", "String()")}}, {{jsxref("Number/Number", "Number()")}}, and {{jsxref("Boolean/Boolean", "Boolean()")}}, can also be called with or without `new`, but the return types differ in the two cases. | ||
|
||
On every constructor page, you can find information about whether the constructor must be called with `new`. | ||
|
||
## Examples | ||
|
||
### Invalid cases | ||
|
||
```js example-bad | ||
const m = Map(); // TypeError: calling a builtin Map constructor without new is forbidden | ||
``` | ||
|
||
### Valid cases | ||
|
||
```js example-good | ||
const m = new Map(); | ||
``` | ||
|
||
## See also | ||
|
||
- {{jsxref("Operators/new", "new")}} |
51 changes: 51 additions & 0 deletions
51
files/en-us/web/javascript/reference/errors/class_ctor_no_new/index.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
--- | ||
title: "TypeError: class constructors must be invoked with 'new'" | ||
slug: Web/JavaScript/Reference/Errors/Class_ctor_no_new | ||
page-type: javascript-error | ||
--- | ||
|
||
{{jsSidebar("Errors")}} | ||
|
||
The JavaScript exception "class constructors must be invoked with 'new'" occurs when a [class constructor](/en-US/docs/Web/JavaScript/Reference/Classes) is called without the {{jsxref("Operators/new", "new")}} keyword. All class constructors must be called with `new`. | ||
|
||
## Message | ||
|
||
```plain | ||
TypeError: Class constructor X cannot be invoked without 'new' (V8-based) | ||
TypeError: Class constructors cannot be invoked without 'new' (V8-based) | ||
TypeError: class constructors must be invoked with 'new' (Firefox) | ||
TypeError: Cannot call a class constructor without |new| (Safari) | ||
``` | ||
|
||
## Error type | ||
|
||
{{jsxref("TypeError")}} | ||
|
||
## What went wrong? | ||
|
||
In JavaScript, _calling_ a function without `new` and _constructing_ a function with `new` are two distinct operations, and functions can behave differently depending on how they are called. | ||
|
||
Traditionally, JavaScript functions have been used as both constructors and normal functions, and can detect how they were called using [`new.target`](/en-US/docs/Web/JavaScript/Reference/Operators/new.target). However, class constructors are always constructors and cannot be called as normal functions. | ||
|
||
## Examples | ||
|
||
### Invalid cases | ||
|
||
```js example-bad | ||
class X {} | ||
|
||
X(); // TypeError: class constructors must be invoked with 'new' | ||
``` | ||
|
||
### Valid cases | ||
|
||
```js example-good | ||
class X {} | ||
|
||
new X(); | ||
``` | ||
|
||
## See also | ||
|
||
- [Classes](/en-US/docs/Web/JavaScript/Reference/Classes) | ||
- {{jsxref("Operators/new", "new")}} |
66 changes: 66 additions & 0 deletions
66
...n-us/web/javascript/reference/errors/constructor_cant_be_used_directly/index.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
--- | ||
title: "TypeError: Iterator/AsyncIterator constructor can't be used directly" | ||
slug: Web/JavaScript/Reference/Errors/Constructor_cant_be_used_directly | ||
page-type: javascript-error | ||
--- | ||
|
||
{{jsSidebar("Errors")}} | ||
|
||
The JavaScript exception "Iterator constructor can't be used directly" or "AsyncIterator constructor can't be used directly" occurs when you try to use the {{jsxref("Iterator/Iterator", "Iterator()")}} or {{jsxref("AsyncIterator/AsyncIterator", "AsyncIterator()")}} constructors directly to create instances. These constructors are _abstract classes_ and should only be inherited from. | ||
|
||
## Message | ||
|
||
```plain | ||
TypeError: Abstract class Iterator not directly constructable (V8-based) | ||
TypeError: Iterator constructor can't be used directly (Firefox) | ||
TypeError: Iterator cannot be constructed directly (Safari) | ||
TypeError: Abstract class AsyncIterator not directly constructable (V8-based) | ||
TypeError: AsyncIterator constructor can't be used directly (Firefox) | ||
TypeError: AsyncIterator cannot be constructed directly (Safari) | ||
``` | ||
|
||
## Error type | ||
|
||
{{jsxref("TypeError")}} | ||
|
||
## What went wrong? | ||
|
||
The {{jsxref("Iterator")}} and {{jsxref("AsyncIterator")}} constructors are abstract classes and should not be used directly. They check the value of [`new.target`](/en-US/docs/Web/JavaScript/Reference/Operators/new.target) and throw if it is the same as the constructor itself. The only way to use these constructors is to inherit from them in a subclass and call `super()` in the subclass constructor. The subclass must also define a `next()` method to be useful. | ||
|
||
## Examples | ||
|
||
### Invalid cases | ||
|
||
```js example-bad | ||
new Iterator(); | ||
``` | ||
|
||
### Valid cases | ||
|
||
```js example-good | ||
class MyIterator extends Iterator { | ||
#step; | ||
#end; | ||
constructor(start, end) { | ||
// Implicitly calls new Iterator(), but with a different `new.target` | ||
super(); | ||
this.#step = start; | ||
this.#end = end; | ||
} | ||
next() { | ||
if (this.#step < this.#end) { | ||
return { value: this.#step++, done: false }; | ||
} else { | ||
return { done: true }; | ||
} | ||
} | ||
} | ||
|
||
new MyIterator(); | ||
``` | ||
|
||
## See also | ||
|
||
- {{jsxref("AsyncIterator")}} | ||
- {{jsxref("Iterator")}} |
Oops, something went wrong.