Differences in behavior of constructors when utilizing ES6 shorthand notation

ES6 introduced a new way to initialize objects with functions and properties using shorthand notation.

// ES6 shorthand notation
const obj1 = {
    a(b) {
        console.log("ES6: obj1");
    }
};

// ES5
var obj2 = {
    a: function a(b) {
        console.log("ES5: obj2");
    }
};

obj2.a();
obj1.a();

new obj2.a();
new obj1.a();

Interestingly, the behavior of these notations is different. For example, when trying new obj1.a(), it results in a

TypeError: obj1.a is not a constructor
. On the other hand, new obj2.a() works as expected.

This raises questions about why this discrepancy occurs. Does anyone have insights or resources that can explain this behavior?

Answer №1

The specification does not provide clear guidance on this topic, but we can follow a concise sequence of steps.

We will begin at EvaluateNew, as that is where the behavior in question lies. Step 7 directly addresses our query:

  1. If IsConstructor(constructor) returns false, then a TypeError exception is thrown.

Next, we need to investigate the function IsConstructor.

Both the overview and the detailed steps shed light on this concept:

The operation IsConstructor determines whether the provided argument, an ECMAScript value, is a function object with a [[Construct]] internal method.


  1. If Type(argument) is not Object, return false.
  2. If argument has a [[Construct]] internal method, return true.
  3. Otherwise, return false.

Based on this explanation, it seems like our obj1.a lacks a [[Construct]] internal method. Let's pinpoint where this specification is mentioned.

The relevant section to look into now is PropertyDefinitionEvaluation. The initial step holds a clue:

Invoke DefineMethod from MethodDefinition using argument object.

Calling DefineMethod with just one parameter, object, offers further insight:

Taking object parameters and optional functionPrototype arguments.


  1. If functionPrototype is present, consider the kind as Normal; otherwise, treat it as Method.
  2. Create a closure using FunctionCreate based on the determined kind.

In the absence of functionPrototype as an argument, the kind defaults to Method. Exploring how FunctionCreate handles this revelation is crucial:

  1. If the kind is not Normal, set allocation type as "non-constructor".
  2. Otherwise, designate the allocation type as "normal".
  3. Use FunctionAllocate, considering allocKind parameters, to allocate F accordingly.

This brings us closer to understanding the process. By examining FunctionAllocate in-depth, specifically its handling of allocKind (in this case, "non-constructor"), we unearth details about a function's intrinsic methods.

  1. If the functionKind is "normal", ensure needsConstruct is set to true.
  2. Otherwise, specify needsConstruct as false.

  1. Create an ECMAScript function object F with predefined internal slots as outlined in Table 27, initializing all slots to undefined.

  1. If needsConstruct is true, then

    a. Implement F's [[Construct]] internal method per the definition in section 9.2.2.

    b. Assign "base" to the [[ConstructorKind]] slot of F.

Following these fundamentals, we observe that since the functionKind is not "normal", needsConstruct resolves to false, resulting in the lack of a [[Construct]] internal method assignment. Subsequently, IsConstructor identifies this and returns false, leading to the failure of EvaluateNew.

MDN succinctly summarizes this notion:

All method definitions are non-constructors and attempting to instantiate them will raise a TypeError.

Now armed with this knowledge, you understand the official reasoning behind why such methods do not qualify as constructors.

Answer №2

It appears that the initial conversation took place at this location: https://github.com/rwaldron/tc39-notes/blob/master/es6/2012-07/july-26.md

MM: There are three reasons for this decision:

  • There is precedent in builtins.
  • Using a method as a constructor does not make sense typically.
  • To freeze a class, I would need to freeze the .prototype of the methods on the prototype.

Additionally,

AWB made a suggestion that concise methods should have consistency between classes and object literals.

  • Strictness
  • Enumerability
  • Constructability
  • Attributes

This led to both class methods and object methods being non-constructable.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Executing code asynchronously and handling callbacks using Process.nextTick and Promise

When I execute the following code: process.nextTick(() => console.log(8)) Promise.resolve("hi").then(t => console.log(t)) console.log(7); The output displayed is 7 8 hi This behavior is as expected because process.n ...

Executing a function without using the eval() function

I am currently working on a JavaScript code that relies heavily on the eval function. eval(myString) The value of myString is equal to myFunc(arg), and I would like to find a way to call myFunc directly instead of using eval. Unfortunately, I have no co ...

Tips for Creating an Animated Progress Bar in a Slider

After implementing jQuery, I managed to create a unique slider on my website. This slider included a thumbnail with captions for each photo. Positioned below the thumbnail was a progress bar fixed in the center between the caption and the image. Users can ...

Paper.js - generate a collection of movable shapes

I am attempting to use paper.js to create draggable shapes where the index of each shape is provided during dragging. Unfortunately, I keep encountering an error that says "Uncaught TypeError: Cannot read property 'position' of undefined". If a ...

Display elements exclusively when the class XY is in an active state using JavaScript

Hello everyone, I'm new to this platform and excited to share my first post. Currently, I find myself facing a major challenge as I navigate through a bootcamp program. I have been working on a website with different sections that require specific fu ...

Tips on how to collapse all elements whenever one is being opened in a FAQ card using ReactJS

Clicking on a question reveals its text, and clicking on another collapses the previous one. The issue arises when trying to close an open question by clicking on it again - it doesn't work as intended due to a potential error in the If statement [im ...

Tips on retrieving and sending an XML string in PHP to JavaScript using MySQL

Here is the code snippet I have: <input type='button' value='clickme' onclick='download(\"\" . $rowtable['Protocolo'] . \".xml\", \"\" . $rowtable['XML&a ...

Determining Velocity of an Object in Three.js

Can anyone help me figure out how to calculate an object's velocity in three.js? I've checked the Object3D documentation but can't seem to find anything related to velocity. Appreciate any assistance, ...

What is the best way to iterate through an array and make use of index values while removing any empty elements along the

In my current setup, I have defined two arrays keyVals and rows: keyVals = [ "Status", "ErrorHeading", "ErrorDetail" ] rows = [ { "Hostname": "ABC", "name& ...

Transform ISO-8859-1 encoding into UTF-8

Recently, I encountered an issue while sending a HTTP request using jQuery's ajax. The server, unfortunately, returns the response in ISO-8859-1 format while my page is set to UTF-8. This discrepancy causes some characters to become unreadable. How ...

Tips for implementing collapsible mobile navigation in Django with the help of Materialize CSS

I'm facing some issues with implementing a responsive navbar that collapses into a 'hamburger bar' on mobile devices and in split view. I have managed to display the hamburger bar, but when I click on it nothing happens. Here's my curre ...

Work with JSON array objects

I am a novice in javascript and JSON. I have a requirement to process each JSON object, as shown in the example prototype below. Can someone please assist me in solving this problem? I need to log each room number given in the JSON sample below. How can I ...

Issues with Async Ajax functionality are being reported specifically in Safari browsers when a redirect

Encountering issues with an async Ajax call not functioning in Safari while working perfectly fine in other browsers. The problem arises when there is a redirect/link on the button or anchor that triggers the Ajax function. Here's a basic example: & ...

Is PHP-generated HTML not responding to external Javascript?

I have been attempting to create a form where, upon checking a checkbox, the onClick() event will enable a select option. Below is my PHP code: function generateOption() { for($x = 0; $x < 10; $x++) { echo "<option value='".$x."'> ...

What are the steps to resolve the error "TypeError: req.next is not a function"?

I've been working on a project and keep encountering this persistent error that I can't seem to fix. I understand the issue, but unfortunately, I'm at a loss as to how to resolve it. Here is the error message: events.js:292 throw er; ...

React Redux - There is an error during rendering as expected props have not been received yet

After retrieving data from an API and storing it in the Redux state, I utilize a helper function within mapStateToProps to filter and modify a portion of that data before passing it along as props. Although everything appears to be functioning correctly b ...

Employing a lexicon of hexadecimal color code values to harmonize CSS styles

I have a unique requirement where I need to utilize a dictionary of HTML color codes and then apply those colors as styles. It's an interesting challenge! Here is an example of how my color dictionary looks like: const colorCodes = { red: ...

Jquery Issue: Safari Leaves Alert Messages Unclosed When Opening Next Alert

I am experiencing an issue in Safari Browser and need some help with the following scenarios (with Example). When I click a button to delete an account, an alert message pops up. This alert window has two actions - "OK" and "Cancel". If I click "OK", it r ...

Update the array by incorporating a new object that corresponds to a provided list with a unique key-value pair

When selecting objects from a list using a checkbox, I want to make the selection recognizable by adding a new key-value pair to the selected objects with the label of the selected value. This is what I have tried: var checkCheckboxOnOff = [{"fieldName": ...

Trouble with jQuery event.keyCode in detecting alphanumeric characters

I recently developed a script that is supposed to detect the key the user clicks and perform an action based on whether it is alphanumeric. However, I am encountering an issue as the script does not seem to be working as expected, and I am not receiving an ...