我正在寻找一种方法来创建具有属性回退的相同类型的嵌套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
}
});
}
答案 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);