javascript – 构造函数使用ES6简写表示法表现不同

ES6引入了一个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();

但是,正如您所看到的,这些不同的符号表现不同.如果我在浏览器中做了新的obj1.a()(测试过Chrome和Firefox),我会得到一个TypeError:obj1.a不是构造函数. new obj2.a()表现完全正常.

这里发生了什么?有没有人有解释,和/或文档/规范的链接?

解决方法:

specification对解释这个问题不是很直接,但我们可以遵循一个短链..

我们将从EvaluateNew开始,因为这是我们想知道的行为.第7步显然是我们在这里寻找的那个:

  1. If IsConstructor(constructor) is false, throw a TypeError exception.

所以IsConstructor是我们下一步要看的地方.

摘要和步骤都描述了这一点:

The abstract operation IsConstructor determines if argument, which must be an ECMAScript language 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. Return false.

因此,根据它的外观来判断,我们的obj1.a没有[[Construct]]内部方法.让我们来看看它不应该有一个……

这是我们正在寻找的东西,PropertyDefinitionEvaluation.第一步在这里很有用:

Let methodDef be DefineMethod of MethodDefinition with argument object.

只用一个参数,即对象来调用DefineMethod.让我们看一下DefineMethod – 这就是我们需要的:

With parameters object and optional parameter functionPrototype.


  1. If functionPrototype was passed as a parameter, let kind be Normal; otherwise let kind be Method.
  2. Let closure be FunctionCreate(kind, [more arguments snipped]).

由于functionPrototype未作为参数传递,因此类型为Method.让我们来看看FunctionCreate的用途:

  1. If kind is not Normal, let allocKind be "non-constructor".
  2. Else, let allocKind be "normal".
  3. Let F be FunctionAllocate([other arguments snipped], allocKind).

现在我们越来越近了!我们只需要看一下FunctionAllocate与allocKind(根据上面的步骤是“非构造函数”),这就是函数所有内部方法等等.

  1. If functionKind is "normal", let needsConstruct be true.
  2. Else, let needsConstruct be false.

  1. Let F be a newly created ECMAScript function object with the internal slots listed in 07007. All of those internal slots are initialized to undefined.

  1. If needsConstruct is true, then

    a. Set F‘s [[Construct]] internal method to the definition specified in 9.2.2.

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

最后!如果我们通过相关步骤,我们可以看到,因为functionKind不是“正常”,needsConstruct变为false,所以永远不会分配[[Construct]]内部方法!然后IsConstructor看到并返回false,因此EvaluateNew失败.

MDN非常简单地描述了这种行为:

All method definitions are not constructors and will throw a TypeError if you try to instantiate them.

..但是现在你们知道他们不是正式的建造者.

上一篇:计算机网络之安全电子邮件


下一篇:如何实现与FDA保持邮件通信安全加密