nic*_*ank 10 javascript methods shorthand ecmascript-6
ES6引入了一种简写符号来初始化具有函数和属性的对象.
// 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();Run Code Online (Sandbox Code Playgroud)
但是,正如您所看到的,这些不同的符号表现不同.如果我new obj1.a()在浏览器中(测试过的Chrome和Firefox),我会得到一个TypeError: obj1.a is not a constructor.new obj2.a()表现完全正常.
这里发生了什么?有没有人有解释,和/或文档/规范的链接?
Flo*_*rie 10
该规范是不是这个解释很直接,但是我们可以按照短链..
我们将从EvaluateNew开始,因为这是我们想知道的行为.第7步显然是我们在这里寻找的那个:
- 如果IsConstructor(构造函数)为false,则抛出TypeError异常.
所以IsConstructor是我们接下来要看的地方.
摘要和步骤都描述了这一点:
抽象操作IsConstructor确定参数(必须是ECMAScript语言值)是否是具有[[Construct]]内部方法的函数对象.
- 如果Type(参数)不是Object,则返回false.
- 如果参数有[[Construct]]内部方法,则返回true.
- 返回false.
所以,从它的外观来看,我们obj1.a没有[[Construct]]内部方法.让我们来看看它不应该有一个......
这是我们正在寻找的东西,PropertyDefinitionEvaluation.第一步在这里很有用:
让methodDef成为MethodDefinition的DefineMethod with argument object.
这只使用一个参数object来调用DefineMethod.让我们看一下DefineMethod - 这就是我们需要的:
带参数对象和可选参数functionPrototype.
- 如果functionPrototype被作为参数传递,让一种是
Normal; 否则让那种会Method.- 让闭包为FunctionCreate(kind,[更多参数剪断]).
由于functionPrototype是不作为参数传递,种类Method.让我们看一下FunctionCreate对它的作用:
- 如果那种不
Normal,让allocKind是"non-constructor".- 另外,让allocKind成为
"normal".- 设F为FunctionAllocate([其他参数剪切],allocKind).
现在我们越来越近了!我们只需要看看FunctionAllocate对allocKind的影响("non-constructor"按照上面的步骤),这就是函数的所有内部方法等等.
- 如果是functionKind
"normal",则let needsConstruct为true.- 否则,让needsConstruct为假.
- 设F是新创建的ECMAScript函数对象,其中内部插槽列于表27中.所有这些内部插槽都初始化为未定义.
如果needsConstruct为true,那么
一个.将F的[[Construct]]内部方法设置为9.2.2中指定的定义.
湾 将F的[[ConstructorKind]]内部插槽设置为
"base".
最后!如果我们通过相关步骤,我们可以看到,因为functionKind不是"normal",needsConstruct变为false,所以永远不会分配[[Construct]]内部方法!然后IsConstructor看到并返回false,因此EvaluateNew失败.
MDN非常简单地描述了这种行为:
所有方法定义都不是构造函数,如果您尝试实例化它们,则会抛出TypeError.
..但现在你知道怎么他们不是构造函数,正式.
| 归档时间: |
|
| 查看次数: |
264 次 |
| 最近记录: |