2013-04-23 74 views
1

我正在寻找一种方法来创建与属性fallbacking相同类型的嵌套的js对象。嵌套相同类型的JavaScript对象与属性后备?

我希望能够写例如:

state.isLoggedIn如果这个对象没有这个属性(未定义),那么它应该在基础状态等,直到没有碱基状态已经存在,然后返回undefined。

有了基态,我的意思是这个状态基于的其他状态,而不是类继承的继承。

我想做出某种类的这样的:

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

当我试图从一个基于另一种状态B时的状态的属性P,以及状态的不定义一个属性P它应该在状态B中查看。

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

在C#中它会是这个样子(并使其成为一个动态的对象,我会得到几乎excatly一样躲开了输入状态,我在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; } 
    } 
} 

任何想法?可能?

UPDATE:

这是我现在得到:

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

为什么不能继承?原型继承看起来就像你正在寻找的东西。 – bfavaretto 2013-04-23 17:12:18

+0

我不能使用预定义的继承链具有不同的状态类。 – 2013-04-24 10:08:16

回答

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不被旧版本浏览器的支持,但一个很简单的填充工具可用on MDN

+0

谢谢!这正是我正在寻找的。另一种方法(__extends)似乎复制了属性值,所以不可能修改父状态,并且如果反映在子状态中。但是用这种方法它工作得很好。我可以改变state1.a并让state2.a返回相同的新值。 – 2013-04-24 10:15:36

0

这就是CoffeeScript中使用类extenstions(使用原型继承):

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); 
+0

握着你的马! =)我不在寻找如何进行原型继承。我正在寻找如何嵌套js对象,并使用父 - 属性作为后备的属性找不到被调用的对象。 – 2013-04-23 17:24:18

+0

@AndreasZita是啊。我不知道你的意思是什么...... – Neal 2013-04-23 17:25:07

+2

@AndreasZita这正是原型继承可以完成的事情之一。 :) – cdhowie 2013-04-23 17:28:51