“;新的“;关键字工作,如ECMAScript 5标准中所述
How does the "new" keyword work as described in ECMAScript 5 standard
我想知道new
运算符是如何工作的,而不仅仅是学习如何使用它。我查看了ECMAScript 5标准,发现算法描述了它的工作方式,但对它的含义有点困惑。
生产
NewExpression : new NewExpression
评估为如下:
- 设
ref
为NewExpression的求值结果- 设
constructor
为GetValue(ref)- 如果
Type(constructor)
不是Object
,则引发TypeError
异常- 如果
constructor
未实现[[Construct]]
内部方法,则引发TypeError
异常- 返回在
constructor
上调用[[Construct]]
内部方法的结果,不提供任何参数(即参数的空列表)
我试着用这个例子来理解上面的算法:
var f = function() {};
var h = new f();
特别是我不理解第一步,因此无法遵循其他步骤。
- 设CCD_ 13为NewExpression的求值结果
var h = new f();
~~~ ~~~~
| '_________ NewExpression
new operator
这是否意味着ref
是f()
的值?但它是undefined
。
3。如果
Type(constructor)
不是Object
,则抛出TypeError
异常。
但是f
的类型是函数,它会抛出TypeError
异常吗?
5。返回在
constructor
上调用[[Construct]]
内部方法的结果,不提供任何参数(即参数的空列表)。
[[Construct]]
函数的内部属性,在constructor
上调用它有什么意义?
首先,我们必须澄清什么是new NewExpression
,尤其是NewExpression
。这可以在附录A中找到。应用此规则的最常见情况是当您不将参数传递给构造函数时。即
var obj = new F;
其中CCD_ 28是指函数。这就是让你省略括号的规则。
在您的示例(var h = new f();
)中,您有括号,即您传递的是一个空的参数列表,因此此算法不适用。f()
是而不是NewExpression
。
相反,此算法适用于:new MemberExpression Arguments
。它的评估方式几乎相同,算法也可以在§11.2.2中找到,就在你引用的算法之后。
考虑到这一点,让我们一步一步地研究该算法:
1.设CCD_ 33是对CCD_。
在您的示例中,MemberExpression
是f
,即它是一个变量。评估的结果是一个特殊的参考对象。这里并不重要它到底是什么。只要知道它包含关于如何从变量中实际获取值的信息
所以现在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;
};
让我们一步一步地进行
- 解决类似
new window['foo' + 1 + 'bar']
->new window.foo1bar
的问题 - 确定实际引用的对象:什么是
window
?全局对象的局部变量或属性 - 这是显而易见的
- 不那么明显,但重点是:每个
Function
都是构造函数,但不是每个构造函数都是Function
。这一点确保了new
只在构造函数上被调用 - 运行构造函数。请注意,规范还为
new foo(...)
提供了MemberExpression : new MemberExpression Arguments
- 创建一个类似链接的按钮,并通过Javascript函数打开一个新的弹出窗口
- Firebase迁移-简单的Firebase.set没有'不再工作了——旧的还是新的
- 使用jquery将mysql数据获取到新的表行中
- 操作员”;新的“;根据我想在几个JavaScript文件中使用的类,在JavaScript中使用
- Javascript 新的 Array 和 join() 方法
- javascript处理一个对象数组以获得一个新的对象数组
- 两个指令创建新的继承的和隔离的作用域-元素得到哪个
- 一次又一次地在新的和相同的选项卡中打开一个url
- 为什么要做新的.Date()与new相差1小时.日期().到ISOString()
- 为什么我们在ES2015中需要一个新的for循环结构,而我们已经有了for、forEach
- 可以在Javascript中添加新的关键字吗
- 在编译阶段后创建新的DOM树,或者继续使用原始修改的DOM
- 如何通过Primefaces3.5使用JSF2.0验证并在成功的情况下打开一个新的选项卡
- 新的日期函数javascript
- 使用 javascript 打开新的浏览器窗口时出错
- 扩展Nashorn-ecma引擎以添加新的运算符和类型
- Django在使用AJAX时没有接收到新的查询字符串
- 如何检测由新的获取标准发起的请求?我应该如何检测AJAX请求
- “;新的“;关键字工作,如ECMAScript 5标准中所述
- 新的ECMA5 Javascript标准中的argument. calee .name替代