簡體   English   中英

為什么 .assign 對象合並中的 setter/getter 定義不起作用?

[英]Why setter/getter definition in .assign object merge doesn't work?

我正在嘗試在我的 JS 應用程序中實現某種繼承。 這是我所擁有的:

function FooObject(param1, param2) {
   this._param1= param1;
   this._param2= param2;
}

Object.defineProperties(FooObject.prototype, {
    param1:
    {
        get: function () { return this._param1; },

        set: function (val) { this._param1= val; }
    }
});

上面是一個“基類”,好嗎?

然后我定義了另一個對象,它擴展了 FooObject 並添加了更多屬性,通過合並:

  function FooObjectA(param1, param2, param3, param4) {
    FooObject.call(this, param1, someVal);
    this._param2= param2;
    this._param3= param3;
    this._param4= param4;
  }

 FooObjectA.prototype = Object.assign(Object.create(FooObject.prototype),
 {
     constructor: FooObjectA,

    param2:
    {
        get: function () { return this._param2; },

        set: function (val) { this._param2= val; }
    },

   param3:
    {
        get: function () { return this._param3; },

        set: function (val) { this._param3 = val; }
    }

});

現在,如果我想獲取 param3,例如:

  var fooInstance = new FooObjectA();
  
  var p = fooInstance .param3;

那么p不保存 _param3 的值,而是引用 getter 方法。

然后我嘗試了這種方法:

  Object.defineProperties(FooObjectA.prototype, {
  {
   
    param2:
    {
        get: function () { return this._param2; },

        set: function (val) { this._param2= val; }
    },

   param3:
    {
        get: function () { return this._param3; },

        set: function (val) { this._param3 = val; }
    }

});

現在它從 getter 返回值確定。 我對 JavaScript 很陌生,想了解為什么當我將 getter/setter 放入 .assign.. create... 時它不起作用,因為從邏輯上講,我不明白為什么這些 getter 沒有與原型合並對象。

Object.assign讀取屬性的(調用 getter)並將該值作為簡單的數據屬性存儲在目標對象上。

如果您想復制 getter/setter 定義,您需要實現自己的函數來檢查屬性描述符 ( Object.getOwnPropertyDescriptor(obj, "propName") ) 並處理在目標上創建 getter/setter 屬性。

然后 p 不保存 _param3 的值,而是對 getter 方法的引用。

那是一個單獨的問題。 您將一個對象傳遞給Object.assign期望它按照Object.defineProperties的方式進行解釋:

FooObjectA.prototype = smartAssign(Object.create(FooObject.prototype), {
    constructor: FooObjectA,
    param2: {
        get: function() {
            return this._param2;
        },
        set: function(val) {
            this._param2 = val;
        }
    },
    param3: {
        get: function() {
            return this._param3;
        },
        set: function(val) {
            this._param3 = val;
        }
    }
});

如果你想使用這種格式,你需要調用Object.defineProperties來解釋它:

FooObjectA.prototype = smartAssign(Object.defineProperties(Object.create(FooObject.prototype), {
// --------------------------------^
    constructor: FooObjectA,
    param2: {
        get: function() {
            return this._param2;
        },
        set: function(val) {
            this._param2 = val;
        }
    },
    param3: {
        get: function() {
            return this._param3;
        },
        set: function(val) {
            this._param3 = val;
        }
    }
})); // <=== Added )

這是執行此操作的函數的快速草圖(使用 ES5 語法); 你需要測試和強化它,很可能:

var hasOwn = function(obj, prop) { // Paranoia, in case an object overrides it
    return Object.prototype.hasOwnProperty.call(obj, prop);
};
function smartAssign(target) {
    var n, source, key;
    for (n = 1; n < arguments.length; ++n) {
        source = arguments[n];
        for (key in source) {
            if (hasOwn(source, key)) {
                Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
            }
        }
    }
    return target;
}

使用它的實時示例並修復了其他問題:

 var hasOwn = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }; function smartAssign(target) { var n, source, key; for (n = 1; n < arguments.length; ++n) { source = arguments[n]; for (key in source) { if (hasOwn(source, key)) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); } } } return target; } function FooObject(param1, param2) { this._param1 = param1; this._param2 = param2; } Object.defineProperties(FooObject.prototype, { param1: { get: function() { return this._param1; }, set: function(val) { this._param1 = val; } } }); function FooObjectA(param1, param2, param3, param4) { FooObject.call(this, param1, 42); this._param2 = param2; this._param3 = param3; this._param4 = param4; } FooObjectA.prototype = smartAssign(Object.defineProperties(Object.create(FooObject.prototype), { constructor: FooObjectA, param2: { get: function() { return this._param2; }, set: function(val) { this._param2 = val; } }, param3: { get: function() { return this._param3; }, set: function(val) { this._param3 = val; } } })); var fooInstance = new FooObjectA("p1", "p2", "p3", "p4"); console.log(fooInstance.param1); console.log(fooInstance.param3);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM