在JavaScript中实现功能:好的部分

时间:2011-07-23 09:54:59

标签: javascript

我正在阅读JavaScript:好的部分。在书中,定义了beget函​​数。其目的是创建并返回一个新对象,该对象使用另一个对象作为其原型。为什么beget函​​数实例化一个新函数而不是一个对象?

if( typeof Object.beget !== 'function' ){
    Object.beget = function(o){
          var F =new Function(){}; // this line, why it cannot be var F = new Object();
          F.prototype = o;
          return new F();
    }
}

7 个答案:

答案 0 :(得分:26)

这与new关键字有关。在JavaScript中,new仅适用于函数(这是一种特殊类型的对象)。

  • 如果您对任何功能使用new,您将获得一个对象。

    alert(typeof console.log); // function
    var dumb = new console.log();  // dumb is an object
    
  • 您获取的对象类型取决于该函数的原型对象。

    alert(typeof console.log.prototype); // object, any new objects created by the new keyword will be of this type.
    alert(typeof Function.prototype); // function, new objects are functions.
    alert(typeof new Function()); // function, see?
    alert(typeof (function(){})); // function, using literal syntax, equivalent
    
  • 您可能已经从上面注意到Function本身就是一个功能。实际上,所有内置构造函数都是函数(函数,对象,数字,数组等)。大写只是区分你如何使用函数的惯例。

所以回到你的问题,作者使用一个空的Function对象只是因为它可以用作构造函数。物体不能。 然后他更改构造函数的原型,以便返回该类型的对象。

Object.beget = function(o) {
    var F = new Function(); // now F can be used as a constructor. 
    F.prototype = o; // All new objects F creates will be based on o.
    return new F();
};

答案 1 :(得分:5)

要添加以前的答案并避免一些混淆,此beget()函数已通过errata替换为create(),因此不同的图书似乎有不同版本的代码。 Safari Books Online上的这本书的印刷方式如下:

if (typeof Object.create !== 'function') {
    Object.create = function (o) {
        var F = function () {};
        F.prototype = o;
        return new F();
    };
}

请注意,它不再鼓励在第3​​行使用new关键字。

答案 2 :(得分:2)

在我看来,正如MDN所说的

  

new运算符创建一个用户定义的对象类型的实例,或者一个具有构造函数的内置对象类型的实例。

     
    

语法

         
      

新构造函数[([arguments])]

    
         

参数

         
      

构造

             
        

指定对象实例类型的函数。

      
             

参数

             
        

将使用构造函数调用的值列表。

      
    
  

因此,我必须使用一个函数来创建一个新实例。

例如:

var list = new Array();
typeof Array;//"function"

此Array不是对象,而是构造函数。

答案 3 :(得分:2)

首先,你不能在通用对象上使用(),也不能在不是函数的任何其他东西上使用。您将收到类似“TypeError:F不是函数”的错误。

答案 4 :(得分:1)

      // create a temporary function
      var F =new Function(){};
      // set the prototype of the function to be o
      F.prototype = o;
      // create a new object from the function
      return new F();

因为这是new的工作方式。 new创建一个新对象并将F.prototype放在原型链中。

new F() === Object.create(F.prototype)

答案 5 :(得分:1)

我的书是

if (typeof Object.beget !== 'function') {
    Object.beget = function (o) {
        var F = function () {};
        F.prototype = o;
        return new F();
    };
}

答案 6 :(得分:0)

你的答案只在书中。 beget方法创建了一个新对象,该对象用作其原型。

下面的行用于检查beget方法是否已经使用过!

if( typeof Object.beget !== 'function' )

然后...... 定义了构造函数 F ,将其原型设置为传入的对象,然后返回一个新实例。