我想知道new
运算符是如何工作的,而不只是学习如何使用它。我查看了ECMAScript 5 standard并找到算法描述它是如何工作的但是对于吝啬有点困惑它的。
生产
NewExpression : new NewExpression
被评估为 如下:
- 让
ref
成为评估NewExpression的结果。- 让
constructor
为GetValue(ref)。- 如果
Type(constructor)
不是Object
,则抛出TypeError
例外。- 如果
constructor
未实施[[Construct]]
内部方法,则抛出TypeError
例外。- 返回在
醇>[[Construct]]
上调用constructor
内部方法的结果,不提供任何参数(即参数的空列表)。
我尝试使用此示例了解上述算法:
var f = function() {};
var h = new f();
特别是我不了解第一步,因此无法遵循其他步骤。
- 让
醇>ref
成为评估NewExpression的结果。
var h = new f();
~~~ ~~~~
| \_________ NewExpression
new operator
这是否意味着ref
是f()
的值?但它是undefined
。
3。如果
Type(constructor)
不是Object
,则抛出TypeError
例外。
但是f
的类型是函数,是否会引发TypeError
异常?
5。返回在
[[Construct]]
上调用constructor
内部方法的结果,不提供任何参数(即,参数的空列表)。
[[Construct]]
函数的内部属性,在constructor
上调用它的含义是什么?
答案 0 :(得分:3)
首先,我们必须澄清new NewExpression
,特别是NewExpression
是什么。这可以在Annex A中找到。此规则适用的最常见情况是您不将参数传递给构造函数。即
var obj = new F;
其中F
指的是一个函数。所以这是允许你省略括号的规则。
在您的示例(var h = new f();
)中,您有括号,即您传递的是一个空的参数列表,因此此算法不适用。 f()
不 NewExpression
。
相反,此算法适用:new MemberExpression Arguments
。它以几乎相同的方式进行评估,并且算法也可以在§11.2.2中找到,就在您引用的算法之后。
考虑到这一点,让我们一步一步地完成该算法:
1。让
ref
成为评估MemberExpression
的结果。
在您的示例中,MemberExpression
是f
,即它是变量。 The result of the evaluation是一个特殊的Reference对象。这里究竟是什么并不重要。只要知道它包含有关如何从变量中实际获取值的信息
所以现在ref
指的是那个参考。
2。让
constructor
成为GetValue(ref)
。
这是实际检索变量的值,constructor
将引用f
引用的函数。
3。让
argList
成为评估Arguments
的结果,生成参数值的内部列表(11.2.4)。
在您的情况下,Arguments
为()
,因此它是一个空列表。
4。如果
Type(constructor)
不是Object
,则抛出TypeError
例外。
重要的是要知道功能是对象!因此,如果在new
表达式中使用了原始值,则此步骤将抛出错误。
5。如果
constructor
未实现[[Construct]]
内部方法,则抛出TypeError
例外。
所有函数(以及可能的其他对象)实现内部[[Construct]]
属性,该属性执行新对象的实际实例化。如果对象没有这样的属性,则不能将其用作构造函数。它的功能如何在§13.2.2中定义。
6。返回在构造函数上调用
[[Construct]]
内部方法的结果,提供列表argList
作为参数值。
这是实际施工的结果。 [[Construct]]
本身就是函数,在§13.2.2中定义。该方法与每个函数相同,负责创建一个新对象,在该新对象上调用该函数并返回该函数或函数返回的任何函数。
以下是JavaScript(部分伪代码)的外观示例:
[[Construct]] = function(F, argList) {
// Create new object that in inherits from F.prototype or Object.prototype
var proto = F.prototype;
var obj = Object.create(typeof proto === 'object' ? proto : Object.prototype);
// Call F with this set to obj and pass the argument list
var result = F.apply(obj, argList);
// If result is not an object, return the generated object
return typeof result === 'object' ? result : obj;
};
答案 1 :(得分:2)
让我们一步一步地了解
new window['foo' + 1 + 'bar']
- >等问题。 new window.foo1bar
window
?全局对象的局部变量或属性?Function
都是构造函数,但不是每个构造函数都是Function
。这一点确保new
仅在构造函数上调用。MemberExpression : new MemberExpression Arguments
new foo(...)
醇>