嵌套具有属性回退的同类型javascript对象

Nesting same type JavaScript-objects with property fallbacking?

本文关键字:同类型 javascript 对象 回退 属性 嵌套      更新时间:2023-09-26

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

我希望能够写,例如:

状态。如果这个对象没有这个属性(undefined),那么它应该在base-state等中查找,直到不再存在base-states,然后返回undefined。

基态是指这个状态所基于的其他状态,而不是像类继承那样被继承。

我想做一个这样的类:

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

当我试图从基于另一个状态B的状态a中获取属性p时,状态a没有定义属性p,它应该去状态B中查找。

我知道我可以使用像state.getState(key)这样的函数,它首先查看自己的属性,然后查看基本属性。但我正在寻找一种方法,这样做的正常属性,而不是。

在c#中,它看起来像这样(并使它成为一个动态对象,我将得到几乎完全相同的ducked类型状态,我在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
        }
    });
}

不确定这是否是你要找的,但也许它是:

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是可用的MDN。

这是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);