javascript - 在 Javascript 中复制属性

标签 javascript

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,现在我们如何使用它来将Object y中的所有属性复制到Object 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”的改造/重写有关


我编辑了我的测试代码。对不起!

最佳答案

prototype中定义this的目的是让每个Object都可以将其作为成员函数调用,如下所示:

yourobject.extend(anotherObject);

大多数编码员发现这比将两个对象作为参数传递更优雅,如下所示:

extend(yourObject, anotherObject);

修改原型(prototype)是向对象添加有用“方法”的好方法。

旁注:我不建议使用作者的extend代码。它没有正确检查 hasOwnProperty .

关于javascript - 在 Javascript 中复制属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7033811/

相关文章:

javascript - 如何使用javascript将元素的内联CSS设置为默认值?

javascript - 当我更改文件夹时,jquery 脚本不起作用

javascript - 表延迟加载

javascript - 使用 JavaScript 绘制到 HTML5 Canvas 时调整 .png 图像的大小

javascript - jQuery - 自定义触发器无法正常工作

javascript - 停止自动转换为 htmlentities?

javascript - 解释 Node.js 探查器结果中的 * 和 ~

javascript - contrib hls js 跳过 m3u8 的部分内容,如何防止这种情况

javascript - 是否可以使用 ng-keypress 监听方向键?

javascript - 迭代 JSON 对象数组