2013-04-23 3 views
1

Я ищу способ создания вложенных js-объектов одного и того же типа с функцией-fallbacking.Вложенные объекты JavaScript-объектов с сохранением свойств?

Я хотел бы быть в состоянии написать, например:

state.isLoggedIn и если этот объект не обладает этим свойством (неопределенным), то оно должно выглядеть в базовом состоянии и т.д., пока не корпус- состояния существуют больше, а затем возвращаются неопределенными.

В базовом состоянии я имею в виду другое состояние, в котором это состояние основано, а не наследуется, как наследование класса.

Я думал сделать какой-то класс, как это:

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

При попытке получить свойство Р из состояния А, который основан на другом состоянии В, и состояние А не определяет свойство P должно выглядеть в состоянии B вместо этого.

Я знаю, что могу использовать функцию типа state.getState (ключ), которая сначала ищет свои свойства, а затем в свойствах базы. Но я ищу способ сделать это с нормальными свойствами.

В 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; } 
    } 
} 

Есть идеи? Возможное?

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

+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 не поддерживается старыми браузерами, но доступен очень простой полиполк on MDN.

+0

Спасибо! Это именно то, что я искал. Другой метод (__extends), казалось, копировал значения свойств, и поэтому было невозможно изменить родительское состояние и иметь, если оно отражено в дочернем состоянии. Но с этим методом он работает отлично. Я могу изменить state1.a и иметь state2.a вернуть то же новое значение. –

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-объекты и использовать родительские свойства в качестве резерва для свойств, не найденных в вызываемом объекте. –

+0

@AndreasZita да. Я понятия не имею, что вы имеете в виду ... – Neal

+2

@AndreasZita Это именно то, что может сделать прототипное наследование. :) – cdhowie

Смежные вопросы