0

Я действительно стонаю с John Resig's simple inheritance method. У этого есть хороший синтаксис, и this._super супер мощный.Наследование класса Javascript с этим ._super и соответствующие дескрипторы defineProperty

Это 2014 жесткий, и я хочу, чтобы определить геттеры & сеттеры вместе с другими дескрипторами (но по-прежнему поддерживать простоту версии Resig, если это возможно).

Как бы я узнал об этом, сохранив синтаксис, родственный Resig's, который я так люблю?

Моя мечта что-то вроде этого:

var Person = Class.extend({ 
    init: function(isDancing){ 
    this.dancing = isDancing; 
    }, 
    dance: function(){ 
    return this.dancing; 
    } 
    tools: {     // <---- this would be so awesome 
    get: function() { ... }, 
    set: function(v) { ... }, 
    enumerable: true 
    }, 
}); 

var Ninja = Person.extend({ 
    init: function(){ 
    this._super(false); 
    }, 
    dance: function(){ 
    // Call the inherited version of dance() 
    return this._super(); 
    }, 
    swingSword: function(){ 
    return true; 
    }, 
    tools: { 
    get: _super,   // <---- and this too 
    set: function(v) { 
     this._super(v); 
     doSomethingElse(); 
    } 
    } 
}); 
+0

Наследование никогда не ответ! Особенно не в javascript. – doliver

ответ

1

Я не знаю, почему вы хотите сделать это, так как вы можете легко обойти это по природе объектов JavaScript, но мне понравился дух ваш вопрос.

Вместо того, чтобы определять метод в вашем классе, я понял, почему бы не определить его для всех классов? В коде eJohn я добавил две функции сразу после объявления прототипа в качестве переменной. Это немного длиннее для StackOverflow, поэтому, пожалуйста, посмотрите this cool pen I made для более наглядного примера.

...// Instantiate a base class (but only create the instance, 
// don't run the init constructor) 
initializing = true; 
var prototype = new this(); 
initializing = false; 

prototype.set = function (attr, val) { 
    return this[attr] = val; 
} 

prototype.get = function (attr) { 
    return this[attr]; 
} 

// Copy the properties over onto the new prototype ... 

И тогда ваши классы будут выглядеть следующим образом:

var Person = Class.extend({ 
    init: function(isDancing){ 
    this.dancing = isDancing; 
    }, 
    dance: function(){ 
    return this.dancing; 
    } 
}); 

var Ninja = Person.extend({ 
    init: function(){ 
    this._super(false); 
    }, 
    dance: function(){ 
    // Call the inherited version of dance() 
    return this._super(); 
    }, 
    swingSword: function(){ 
    return true; 
    }, 
    set: function (attr, val) { 
    this._super(attr, val); 
    console.log('doing other things'); 
    } 
}); 

Так что вы можете делать такие вещи, как это:

var p = new Person(true); 

p.get('dancing');  // => true 
p.set('dancing', false); // Telling the person to please stop dancing (he's drunk) 
p.dance();    // => false... "whew!" 
p.get('dancing')   // => false - he must be asleep 

var n = new Ninja(); 

n.get('dancing');  // => false, ninjas don't dance 
n.set('dancing', true); // except my ninjas do 
n.get('dancing');  // => true, cause they're rad 
+0

Это супер удивительно, но он не использует собственные дескрипторы ECMAScript5. Я думаю, что реальный способ обойти это (читай: hacky) - это отредактировать функцию клонирования свойств, чтобы проверить, есть ли значение, get или set, key, а затем передать его Object.defineProperty. Может быть. Я не знаю, будет ли это работать. Собираюсь проверить это. –

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