1

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

我希望能够写例如:

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

对于基本状态,我的意思是该状态所基于的其他状态,而不是像类继承那样继承。

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

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

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

我知道我可以使用像 state.getState(key) 这样的函数,它首先查看自己的属性,然后查看基本属性。但我正在寻找一种使用普通属性执行此操作的方法。

在 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
        }
    });
}
4

2 回答 2

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旧浏览器不支持,但MDN上提供了一个非常简单的 polyfill 。

于 2013-04-23T23:02:06.833 回答
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);
于 2013-04-23T17:13:22.707 回答