0

我真的很喜歡John Resig's simple inheritance method。它有很好的語法,this._super超級強大。Javascript類繼承w/this this._super和正確defineProperty描述符

這是2014年的艱難,我希望能夠與其他描述符一起定義getters & setter(但如果可能,仍然保持Resig版本的簡單性)。

我會如何解決這個問題,同時保持類似於我喜歡的Resig的語法?

我的夢想是這樣的:

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 2014-08-29 03:02:42

回答

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)是編輯屬性克隆函數,以檢查是否存在值,獲取或設置鍵,然後將其傳遞給Object.defineProperty。也許。我不知道這是否會奏效。要測試它。 – 2014-08-29 02:37:20