我想知道new运算符是如何工作的,而不仅仅是学习如何使用它。


  生产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


这是否意味着reff()的值?但这是undefined


  3。如果Type(constructor)不是Object,则引发TypeError异常。


但是f的类型是函数,会抛出TypeError异常吗?


  5。返回不提供任何参数(即空参数列表)的在[[Construct]]上调用constructor内部方法的结果。


[[Construct]]函数的内部属性,在constructor上调用它的含义是什么?

最佳答案

首先,我们必须弄清楚什么是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的结果。


在您的示例中,MemberExpressionf,即它是一个变量。 The result of the evaluation是特殊的Reference对象。到底是什么并不重要。只要知道它包含有关如何实际从变量中获取值的信息。
因此,现在ref引用该引用。


  2.设constructorGetValue(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;
};

关于javascript - 如ECMAScript 5标准所述,“new”关键字如何工作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17379709/

10-12 00:54