Skip to content

Commit

Permalink
Add reference for errors related to classes (#34791)
Browse files Browse the repository at this point in the history
  • Loading branch information
Josh-Cena authored Jul 19, 2024
1 parent 2f47cba commit b736420
Show file tree
Hide file tree
Showing 8 changed files with 599 additions and 0 deletions.
112 changes: 112 additions & 0 deletions files/en-us/web/javascript/reference/errors/bad_super_call/index.md
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")}}
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")}}
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")}}
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")}}
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")}}
Loading

0 comments on commit b736420

Please sign in to comment.