我正在阅读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();
}
}
答案 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 ,将其原型设置为传入的对象,然后返回一个新实例。