Object.defineProperty 带有构造函数和原型

Ale*_*rck 3 javascript properties

我刚刚发现Object.defineProperty并且因为我对 C# 最熟悉,所以我想在构造函数中使用访问器属性,例如:

function Base(id) {
   var _id = id;

   Object.defineProperty(this,"ID",{
       get: function() { return _id; },
       set: function(value) { _id = value; }
   })
}

function Derived(id, name) {
   var _name = name;

   Base.call(this,id);

   Object.defineProperty(this,"Name",{
      get: function() { return _name; },
      set: function(value) { _name = value; }
   })
}

Derived.prototype = Object.create(Base.prototype);
Derived.constructor = Derived;

var b = new Base(2);
var d = new Derived(4,"Alexander");

console.log(b.ID);
console.log(d.ID, d.Name);
d.ID = 100;
console.log(d.ID, d.Name);
Run Code Online (Sandbox Code Playgroud)

这打印:

2
4 “亚历山大”
100 “亚历山大”

但是我对此感到非常困惑,例如这个得分很高的答案鼓励上述方法,而这个答案说它会占用所有内存,因为将为我实例化的每个对象重新创建函数。它建议采用以下方法:

var Base = function(id){this.__id = id}
Player.prototype = {
   get ID(){
      return this.__id;
   },
   set ID(value){
      this.__id = value;
   }
}

var p = new Player();
p.ID = 2;
alert(p.ID); // 4
Run Code Online (Sandbox Code Playgroud)

然而,这种方法也创建了另一个__id对我来说似乎不太理想的公共属性(我的示例中的属性是“特权”的,因为它在 javascript 中显然是调用的,因此不需要额外的公共属性)。

有人可以解释一下哪种方法适合我吗?现在我完全迷失在 javascript 文档丛林中。我非常喜欢这种Object.defineProperty方法,因为我觉得代码很干净,我可以将它与继承一起使用。但是,如果确实为每个对象重新创建了函数,我可能需要考虑第二种方法吗?

Ber*_*rgi 5

有人可以解释一下哪种方法适合我吗?

根本不要用Object.defineProperty。您在这里绝对不需要属性描述符,并且您的 getter 和 setter 没有做任何特别的事情。只需使用一个简单的普通属性。它将比您关心的其他任何事情都更快、优化得更好。

function Base(id) {
    this.ID = id;
}

function Derived(id, name) {
    Base.call(this,id);
    this.Name = name;
}

Derived.prototype = Object.create(Base.prototype);
Derived.prototype.constructor = Derived;
Run Code Online (Sandbox Code Playgroud)

如果确实为每个对象重新创建了函数,我可能需要考虑第二种方法吗?

是的,这是真的,但可以忽略不计。您不应该过早地进行微观优化。您将知道何时真正需要它,然后您仍然可以轻松地交换实现。在此之前,请选择干净简单的代码。