Javascript - 权威指南(6ed)显示以下代码:
最初我们有这个功能
/*
* Copy the enumerable properties of p to o, and return o.
* If o and p have a property by the same name, o's property is overwritten.
* This function does not handle getters and setters or copy attributes.
*/
function extend(o, p) {
for(prop in p) { // For all props in p.
o[prop] = p[prop]; // Add the property to o.
}
return o;
}
然后作者决定重写它并扩展复制能力(例如,能够复制存取器属性):
/*
* Add a nonenumerable extend() method to Object.prototype.
* This method extends the object on which it is called by copying properties
* from the object passed as its argument. All property attributes are
* copied, not just the property value. All own properties (even non-
* enumerable ones) of the argument object are copied unless a property
* with the same name already exists in the target object.
*/
Object.defineProperty(Object.prototype,
"extend", // Define Object.prototype.extend
{
writable: true,
enumerable: false, // Make it nonenumerable
configurable: true,
value: function(o) { // Its value is this function
// Get all own props, even nonenumerable ones
var names = Object.getOwnPropertyNames(o);
// Loop through them
for(var i = 0; i < names.length; i++) {
// Skip props already in this object
if (names[i] in this) continue;
// Get property description from o
var desc = Object.getOwnPropertyDescriptor(o,names[i]);
// Use it to create property on this
Object.defineProperty(this, names[i], desc);
}
}
});
我不明白我们为什么要扩展 Object.prototype ,现在我们如何使用它来将对象y 中的所有属性复制到对象X ?我如何使用 Object.prototype.extend ?
我决定测试一下我是否可以更快地做点什么。我不明白为什么以下自定义代码不起作用。
function extend(o){
var p = new Object();
for( prop in o)
Object.defineProperty(p,prop,Object.getOwnPropertyDescriptor(o,prop));
return p;
}
// Let's perform a simple test
var o = {};
Object.defineProperty(o, "x", { value : 1,
writable: true,
enumerable: false,
configurable: true});
o.x; // => 1
Object.keys(o) // => []
var k = new Object(extend(o)); // Good, k.x => 1
// More test
Object.defineProperty(o, "x", { writable: false });
Object.defineProperty(o, "x", { value: 2 });
Object.defineProperty(o, "x", { get: function() { return 0; } });
o.x // => 0
// Perform the creation again
var k = new Object(extend(o)); // bad. k.x is 1, not 0
// so the getter property didn't copy to k !!!
抱歉,我是Javascript的新手。我在这里先向您的帮助表示感谢。所有这些问题都与函数“extend”
的转换/重写有关我编辑了我的测试代码。抱歉!
答案 0 :(得分:3)
在prototype
中定义此内容的目的是让每个Object
都可以将其称为成员函数,如下所示:
yourobject.extend(anotherObject);
大多数程序员发现比将两个对象作为参数传递更优雅,如下所示:
extend(yourObject, anotherObject);
修改原型是向对象添加有用“方法”的好方法。
旁注:我不建议使用作者的extend
代码。它没有正确检查hasOwnProperty。
答案 1 :(得分:1)
您似乎误解了prototype
的使用。原型是JavaScript处理继承的方式。 extend
函数是从C ++和Java等语言借出的术语,并非JavaScript原生。
以下是prototype
:http://mckoss.com/jscript/object.htm
我有几年编写JavaScript的经验,我建议不要使用原型。 JavaScript还有其他处理数据建模的方法,我发现它更优雅。理解原型设计的工作方式仍然有用,因为它加深了您对Objects
的理解。