覆盖[gs]和javascript对象实例的最佳方法(使用原型?)

时间:2015-05-26 13:02:06

标签: javascript node.js

示例代码我希望实例如何工作:

var brother = new Person("James");

console.log(brother.status);
// "James, current location: home, health condition: saber"

brother.status = {
    location: "pub",
    "health condition": "drunk as a skunk"
};

console.log(brother.status);
// "James, current location: pub, health condition: drunk as a skunk"

问题是如何编程对象Person,它的原型以及如何使用Object.defineProperty来实现这种(或类似)行为最优雅的方式。

到目前为止我做了一些解决方案,但我不想在这里解释它来打扰你的想法。

关键答案应包含具有不为每个实例复制的方法和属性的Object,并且Object必须易于继承。

2 个答案:

答案 0 :(得分:1)

// Constructor
function Person(name){
  // In prototype, Can be in herited
  this._name = name;
  this._status;

  // Not available in prototype, hence cannot be inherited
  age = 20;
  function incAge(){
    age++;
  }
  // Available in instances, Privilege.  
  this.getAge = function(){
     incAge();  // Accessing private members
     return age;
  }
}

Person.prototype.constructor = Person;

Object.defineProperty(Person.prototype, "status", {
  configurable : true,  // If you want it to be changed in derived class
  enumerable : false,
  get : function(){
    this._status = this._status || {location : "home", "health condition" : "saber"};
    return this._name + ", current location: "+ this._status.location+", health condition: "+this._status["health condition"];
  },
  set : function(status){this._status = status}
});

//----DERIVED CLASS---  
function SuperPerson(name){
  Person.call(this, name);          
}

SuperPerson.prototype = Object.create(Person.prototype);
SuperPerson.prototype.constructor = SuperPerson;

Object.defineProperty(Person.prototype, "status", {
  enumerable : false,
  get : function(){
    this._status = this._status || {location : "BatCave", "health condition" : "I dont have parents to take care of me"};
    return this._name + ", current location: "+ this._status.location+", health condition: "+this._status["health condition"];
  }
});

This post精美地解释了Object.defineProperty方法的描述符,如果你感兴趣的话。

答案 1 :(得分:1)

您可以为所有人定义公共私有defaultStatus,然后为每个人创建一个继承自status的私有defaultStatus。然后,公开公开status,在设置时,将新数据分配给私人status(我使用ES6 Object.assign,可以是polyfilled)。在获取时,它会构建所需的字符串。

var Person = (function() {
  var defaultStatus = {
    location: 'home',
    health: 'saber'
  };
  return function Person(name) {
    var status = Object.create(defaultStatus);
    Object.defineProperty(this, 'status', {
      enumerable: true,
      get: function() {
        return [
          name,
          "current location: " + status.location,
          "health condition: " + status.health
        ].join(', ');
      },
      set: Object.assign.bind(void 0, status)
    });
  };
})();
相关问题