# Constructor definition

**URL:** <https://es.discourse.group/t/constructor-definition/1923>\
**Category:** I have questions\
**Created:** [February 11, 2024, 1:14am UTC](https://es.discourse.group/t/constructor-definition/1923 "2024-02-11T01:14:46Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![MaineGardener](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/mainegardener/32/2012_2.png) [@MaineGardener](https://es.discourse.group/u/MaineGardener)\
**Post date:** [February 11, 2024, 1:14am UTC](https://es.discourse.group/t/constructor-definition/1923/1 "2024-02-11T01:14:46Z")

</div>

ECMA-262 states that a [constructor](https://262.ecma-international.org/14.0/#constructor) is an object that supports the `[[Construct]]` internal method. I suspect that `BigInt` and `Symbol` support `[[Construct]]` because they are included in [Constructor Properties of the Global Object](https://262.ecma-international.org/14.0/#sec-constructor-properties-of-the-global-object). However, both return a `TypeError` when called with the `new` operator:

```javascript
try {
  console.log(typeof new BigInt(5));
} catch (e) {
  console.log(`${e.name}: ${e.message}`); // TypeError: BigInt is not a constructor
}

try {
  console.log(typeof new Symbol(5));
} catch (e) {
  console.log(`${e.name}: ${e.message}`); // TypeError: Symbol is not a constructor
}

```

Note that the error includes _is not a constructor_.

It is confusing to me and perhaps to others that a constructor is an object that supports the `[[Construct]]` internal method, and `BigInt` and `Symbol` support this internal method, but `BigInt` and `Symbol` are not constructors (per the error messages), and neither support the `new` operator.

(Note: I do understand why `BigInt` and `Symbol` don't support the `new` operator, and why `Boolean` and perhaps others really shouldn't either.)

Why aren't `BigInt` and `Symbol` just function objects that do not support `[[Construct]]` and do not have a seemingly unnecessary `prototype` property? If they were, then the current definition would suffice.

Thanks!

---

<div class="post-metadata">

**Author:** ![jmdyck](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/jmdyck/32/796_2.png) [@jmdyck](https://es.discourse.group/u/jmdyck)\
**Post date:** [February 11, 2024, 2:14am UTC](https://es.discourse.group/t/constructor-definition/1923/2 "2024-02-11T02:14:57Z")

</div>

From the point of view of the spec, `BigInt` and `Symbol` are constructors, and have a `[[Construct]]` internal method, but its behavior is to return a TypeError. So for (most?) practical purposes, they look like not-constructors.

---

<div class="post-metadata">

**Author:** ![bergus](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/bergus/32/152_2.png) [@bergus](https://es.discourse.group/u/bergus)\
**Post date:** [February 11, 2024, 4:08am UTC](https://es.discourse.group/t/constructor-definition/1923/3 "2024-02-11T04:08:58Z")

</div>

> [@MaineGardener](#):
>
> Why aren't `BigInt` and `Symbol` just function objects that […] do not have a seemingly unnecessary `prototype` property?

The `.prototype` is not unnecessary, it is used to supply the methods and getters on `BigInt` and `Symbol` objects.

---

<div class="post-metadata">

**Author:** ![aclaymore](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aclaymore/32/501_2.png) [@aclaymore](https://es.discourse.group/u/aclaymore)\
**Post date:** [February 11, 2024, 7:35am UTC](https://es.discourse.group/t/constructor-definition/1923/4 "2024-02-11T07:35:44Z")

</div>

Another way to look at it is that they are _private_ constructors.

```javascript
const i = Object(1n);
i instanceof BigInt; true

```

If `#constructor` became part of the language perhaps BigInt and Symbol would be modelled that way.

---

<div class="post-metadata">

**Author:** ![MaineGardener](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/mainegardener/32/2012_2.png) [@MaineGardener](https://es.discourse.group/u/MaineGardener)\
**Post date:** [February 11, 2024, 11:11am UTC](https://es.discourse.group/t/constructor-definition/1923/5 "2024-02-11T11:11:45Z")

</div>

Like all objects, `BigInt` and `Symbol` have a `[[Prototype]]` internal slot which points to a parent object from which the objects inherit properties. `[[Prototype]]` is different than a `prototype` property which constructors have. A constructor’s `prototype` property points to the object that will become the `[[Prototype]]` value of any instances that it creates. But, and this is my point, `BigInt` and `Symbol` don't create instances because they are incapable of acting like constructors. That's why I'm suggesting that there is no need for `BigInt` and `Symbol` to have a `prototype` property. I diagrammed this distinction in [Diagrams of JavaScript constructors](https://medium.com/hagenhaus/diagrams-of-javascript-constructors-0e348b67dfee).

---

<div class="post-metadata">

**Author:** ![aclaymore](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aclaymore/32/501_2.png) [@aclaymore](https://es.discourse.group/u/aclaymore)\
**Post date:** [February 11, 2024, 12:57pm UTC](https://es.discourse.group/t/constructor-definition/1923/6 "2024-02-11T12:57:01Z")

</div>

As per [Constructor definition - #3 by bergus](https://es.discourse.group/t/constructor-definition/1923/3) and [Constructor definition - #4 by aclaymore](https://es.discourse.group/t/constructor-definition/1923/4), while `new Symbol()` doesn't create an instance of Symbol. These instances do exist and the `.prototype` is used:

```javascript
const s = Symbol("abc");
Object.getPrototypeOf(s) === Symbol.prototype;

Reflect.ownKeys(Symbol.prototype).includes("description"); // true
s.description; // "abc"

```

---

<div class="post-metadata">

**Author:** ![bergus](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/bergus/32/152_2.png) [@bergus](https://es.discourse.group/u/bergus)\
**Post date:** [February 11, 2024, 4:34pm UTC](https://es.discourse.group/t/constructor-definition/1923/7 "2024-02-11T16:34:01Z")

</div>

Yes, were talking about `.prototype` here. Those objects are still getting used as the _[[prototype]]_ for instances that are getting created temporarily when accessing a property on primitives, such as `Symbol("example").description` or `1n.toString()`. You can also explicitly construct them using `Object(Symbol("example"))` or `Object(1n)`.

---

<div class="post-metadata">

**Author:** ![aclaymore](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aclaymore/32/501_2.png) [@aclaymore](https://es.discourse.group/u/aclaymore)\
**Post date:** [February 11, 2024, 5:47pm UTC](https://es.discourse.group/t/constructor-definition/1923/8 "2024-02-11T17:47:56Z")

</div>

> [@MaineGardener](#):
>
> Note that the error includes _is not a constructor_

The spec only defines the type of Error that is thrown, the error message is up to the implementation. It just so happens that many implementations have mutually chosen the same message of "is not a constructor".

---

<div class="post-metadata">

**Author:** ![MaineGardener](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/mainegardener/32/2012_2.png) [@MaineGardener](https://es.discourse.group/u/MaineGardener)\
**Post date:** [February 11, 2024, 6:30pm UTC](https://es.discourse.group/t/constructor-definition/1923/9 "2024-02-11T18:30:47Z")

</div>

Thanks bergus, aclaymore, and jmdyck. Very helpful. It's interesting that the Chrome and Node.js implementations (and surely others) interpret the `TypeError` as "is not a constructor". It suggests to me that (perhaps) the implementation teams do not view `Symbol` and `BigInt` as constructors. I would guess this is because `Symbol` and `BigInt` are the only standard built-in constructors that do not support the `new` operator. Just a guess. If so, though, it suggests that many implementation engineers define a constructor as a function object that supports the `new` operator. I have, too, up to this point. We know, of course, that the spec defines a constructor as a function object that supports `[[Construct]]`. But, I don't know an empirical way to test this. What do you think of the following (testable) definition: A constructor is a function object that possesses a prototype property. I'm thinking this is true in all cases. Thx much.

---

<div class="post-metadata">

**Author:** ![aclaymore](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aclaymore/32/501_2.png) [@aclaymore](https://es.discourse.group/u/aclaymore)\
**Post date:** [February 11, 2024, 6:46pm UTC](https://es.discourse.group/t/constructor-definition/1923/10 "2024-02-11T18:46:09Z")

</div>

> [@MaineGardener](#):
>
> We know, of course, that the spec defines a constructor as a function object that supports `[[Construct]]`. But, I don't know an empirical way to test this

Proxies can be used to check for the `[[Construct]]` slot, because they will only call the 'construct' hook if the target has that slot.

```javascript
function isConstructor(f) {
    if (typeof f !== "function") return false;
    let hasConstructSlot = false;
    try {
      new (new Proxy(f, { construct() { hasConstructSlot = true; } }))();
    } catch {}
    return hasConstructSlot;
}

```

```javascript
isConstructor(123); // false
isConstructor(() => {}); // false
isConstructor(({ method() {} }).method); // false
isConstructor(Set); // true

```

---

<div class="post-metadata">

**Author:** ![MaineGardener](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/mainegardener/32/2012_2.png) [@MaineGardener](https://es.discourse.group/u/MaineGardener)\
**Post date:** [February 11, 2024, 7:37pm UTC](https://es.discourse.group/t/constructor-definition/1923/11 "2024-02-11T19:37:18Z")

</div>

Great. Thanks, aclaymore.

---

<div class="post-metadata">

**Author:** ![MaineGardener](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/mainegardener/32/2012_2.png) [@MaineGardener](https://es.discourse.group/u/MaineGardener)\
**Post date:** [February 11, 2024, 10:12pm UTC](https://es.discourse.group/t/constructor-definition/1923/12 "2024-02-11T22:12:33Z")

</div>

Partially based on this discussion, I modified the definition of _constructor_ in [Diagrams of JavaScript constructors](https://medium.com/hagenhaus/diagrams-of-javascript-constructors-0e348b67dfee). I included the `isConstructor` function though I modified it slightly to make it easier to undertand for readers. I'd be glad to credit you, aclaymore, for this function in my article if you agree. The purpose of the article is to present a clean way to diagram constructors and their instances. Thanks again.
