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

fel*_*lix 15 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

Bri*_*can 26

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

  • 如果你new几乎使用任何函数,你将得到一个对象.

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

    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
    
    Run Code Online (Sandbox Code Playgroud)
  • 你可能从上面注意到它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();
};
Run Code Online (Sandbox Code Playgroud)


mik*_*ail 5

为了增加以前的答案并避免一些混淆,这个beget()功能被create()一个勘误表所取代,所以不同的书籍似乎有不同版本的代码.Safari Books Online上的这本书的印刷方式如下:

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

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


Ray*_*nos 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();
Run Code Online (Sandbox Code Playgroud)

因为这就是new工作原理。new 创建一个新对象并将其放入F.prototype原型链中。

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