使用属性回退嵌套相同类型的JavaScript对象?

时间:2013-04-23 17:09:33

标签: javascript inheritance

我正在寻找一种方法来创建具有属性回退的相同类型的嵌套js对象。

我希望能够写一下:

state.isLoggedIn并且如果此对象没有此属性(未定义),那么它应该查看基本状态等,直到不再存在基本状态,然后返回undefined。

对于基态,我指的是这个状态所依赖的其他状态,而不是像类继承一样继承。

我在考虑制作这样的课程:

function State(base) {
    this.base = base; // also a state
}

当我尝试从基于另一个状态B的状态A获取属性P,并且状态A没有定义属性P时,它应该改为查看状态B.

我知道我可以使用像state.getState(key)这样的函数,它首先在自己的属性中查找,然后在base-properties中查找。但我正在寻找一种用普通属性来做这个的方法。

在C#中它会看起来像这样(并使它成为一个动态对象,我几乎会疯狂地得到我在javascript中寻找的同类型的状态):

class State
{
  public State(State base)
  {
    _base = base;
  }

  State _base;

  Dictionary<string, object> _values = new Dictionary<string, object>();

  public object this[string key]
  {
    get { return _values.ContainsKey(key) ? _values[key] : _base[key]; }
    set { _values[key] = value; }
  }
}

有什么想法吗?可能的?

更新:

这就是我现在所拥有的:

function State() {
}

function ViewModelBase() {
    var self = this;
    self.__parent = ko.observable(null);
    self.state = new State();

    self.parent = ko.computed({
        read: function () {
            return self.__parent();
        },
        write: function (value) {
            if (getObjectClass(value) !== "ViewModelBase") throw new Error("Wrong type of parent.");
            var p = self.__parent();
            if (p != null) throw new Error("Allready parented.");
            self.__parent(value);

            // here i'd like to inherit/nest self.state with value.state
        }
    });
}

2 个答案:

答案 0 :(得分:1)

不确定这是否是您正在寻找的,但可能是:

var state1 = {a : 1};
var state2 = Object.create(state1);
state2.b = 2;
console.log(state2.a); // 1
var state3 = Object.create(state2);
state3.a = 10; // creates an own "a" in state3
console.log(state1.a); // 1
console.log(state2.a); // 1
console.log(state3.b); // 2

这是使用继承,正如我在你对你的问题的原始评论中所建议的那样。 Object.create返回一个新对象,该对象使用作为第一个参数传递的对象作为其[[Prototype]](某些实现通过__proto__属性公开)。当您尝试访问新对象的属性并且找不到自己的属性时,它会在原型链中查找。

旧浏览器不支持

Object.create,但可以使用非常简单的polyfill on MDN

答案 1 :(得分:0)

这就是CoffeeScript用于类扩展(使用原型继承)的原因:

var __hasProp = {}.hasOwnProperty,
__extends = function (child, parent) {
    for (var key in parent) {
        if (__hasProp.call(parent, key)) child[key] = parent[key];
    }
    function ctor() {
        this.constructor = child;
    }
    ctor.prototype = parent.prototype;
    child.prototype = new ctor();
    child.__super__ = parent.prototype;
    return child;
};

这假设类函数都是类函数原型的一部分。


例如:

Animal = (function() {

  function Animal() {}

  Animal.prototype.name = 'Generic Animal';

  Animal.prototype.my_sound = 'none';

  Animal.prototype.sound = function() {
    return console.log(this.my_sound);
  };

  return Animal;

})();

Cow = (function(_super) {

  __extends(Cow, _super);

  function Cow() {
    return Cow.__super__.constructor.apply(this, arguments);
  }

  Cow.prototype.name = 'Cow';

  Cow.prototype.my_sound = 'Moo';

  return Cow;

})(Animal);

Cat = (function(_super) {

  __extends(Cat, _super);

  function Cat() {
    return Cat.__super__.constructor.apply(this, arguments);
  }

  Cat.prototype.name = 'Cat';

  Cat.prototype.my_sound = 'Meow';

  return Cat;

})(Animal);