为什么“新功能”调用该功能?

时间:2013-12-24 18:35:52

标签: javascript date new-operator

我正在玩Date对象,我观察了这个

  1. new Date()//返回Date对象
  2. Date()//以字符串格式返回日期
  3. MDN - Date documentation确认了这个

      

    注意:请注意,JavaScript Date对象只能通过调用JavaScript Date作为构造函数来实例化:将其称为常规函数(即没有new运算符)将返回一个字符串而不是Date对象;与其他JavaScript对象类型不同,JavaScript Date对象没有文字语法。

    棘手部分new Date会返回new Date()返回的相同结果吗?

    我尝试使用普通功能进行相同的实验,

    function f() {
      console.log(' I am executed');
    }
    
    new f
    

    我很惊讶地看到I am executed被记录。我试图找出当我没有使用execution ()运算符时调用f的原因。有人可以解释为什么new称之为方法吗?

    PS:我不知道new f应该给我什么。这是一个语法错误所以我认为它会给我一个错误。但事实并非如此。

3 个答案:

答案 0 :(得分:5)

因为new将调用您正在创建的对象的构造函数。对于函数,该函数既是该对象的对象,也是该对象的构造函数。

答案 1 :(得分:2)

我认为this part of ECMAScript Spec应该解释new运算符的操作。在您的情况下,第一部分为5,第二部分为6。基本上,JS会像函数一样调用构造函数。

  

新操作员

     

生产NewExpression : new NewExpression被评估为   如下:

     
      
  1. 让ref成为评估NewExpression的结果。
  2.   
  3. 让构造函数为GetValue(ref)。
  4.   
  5. 如果Type(构造函数)不是Object,则抛出TypeError异常。
  6.   
  7. 如果构造函数未实现[[Construct]]内部方法,则抛出TypeError异常。
  8.   
  9. 返回在构造函数上调用[[Construct]]内部方法的结果,不提供任何参数(即,一个空列表   参数)。
  10.         

    制作MemberExpression : new MemberExpression Arguments是   评估如下:

         
        
    1. 让ref成为评估MemberExpression的结果。
    2.   
    3. 让构造函数为GetValue(ref)。
    4.   
    5. 让argList成为评估Arguments的结果,生成一个参数值的内部列表(11.2.4)。
    6.   
    7. 如果Type(构造函数)不是Object,则抛出TypeError异常。
    8.   
    9. 如果构造函数未实现[[Construct]]内部方法,则抛出TypeError异常。
    10.   
    11. 返回在构造函数上调用[[Construct]]内部方法的结果,提供列表argList作为参数值。
    12.   

答案 2 :(得分:2)

这是一个“愚蠢”代码的案例 您可能知道the new keyword in javascript can be dangerous:例如,假设您有一个经典的Point构造函数:

function Point(x, y) {
    this.x = x;
    this.y = y;
}

如果通过使用new关键字实例化构造函数来创建点,则此方法可以正常工作。但如果有人忘记使用它呢?以下代码的结果是什么?

var myPoint = Point(0, 0); 

好吧,既然构造函数本身没有返回任何内容(甚至没有return语句),myPoint将是undefined而不是Point实例。所有这些都是因为忘记了new关键字 但不要害怕!您可以将代码编写为愚蠢的代码:

function Point(x, y) {
    // `this` points to the outer scope 
    // if the function is called witouth `new`
    if(!(this instanceof Point))
        return new Point(x, y);

    this.x = x;
    this.y = y;
}

尽管内置了DateArray等功能,我们实际上可以看到它们的来源,但我坚信他们默认使用这种安全机制来阻止新手制造琐碎的愚蠢行为错误。