2013-04-23 72 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