2012-12-13 95 views
1

可能重複:
How do I make a callable JS object with an arbitrary prototype?做一個javascript函數繼承原型

比方說,我們有我們可以在自己的範圍內單獨調用多個單獨的功能;但是他們也繼承了一些其他對象的原型。就像這樣:

//Here is the parent object: 
var Human = function(){ 
    this.isAlive = true; 
}; 
Human.prototype.say = function(what){ 
    alert(what + '!'); 
}; 

//These will inherit from it: 
var ninja = function() { 
    alert("I'm a ninja!"); 
} 
var samurai = function(){ 
    alert("I'm a samurai!"); 
} 

//Now, how can I make ninja and samurai behave like this: 
ninja(); //I'm a ninja! 
samurai(); //I'm a samurai! 
ninja.say('Hello'); //Hello! 

//And they should keep their inheritance. Like: 
Human.prototype.die = function(){ 
    this.isAlive = false; 
} 

ninja.die(); 
ninja.isAlive == false; 

samurai.isAlive == true; 

換句話說,是有辦法有繼承另一個對象的原型,但仍作爲調用函數的兩個對象?

注意:我要在Adobe ExtendScript中使用它(又名支持JavaScript),它不知道現代JavaScript。像,Object.defineProperty不起作用。那麼,有沒有一個正常的,標準的方法來做到這一點?

+0

我不認爲你可以做到這一點沒有聲明'新忍者()',但也許有人可以證明我錯了。 – lbstr

+0

+1好找 - 我會說那個答案證明我錯了 – lbstr

+0

@apslillers是的,我不這些都是相同的問題。 – Aria

回答

3

鏈接的問題使用apsillers的,我能得到它的一個調整工作:Human的屬性和方法被定義爲一個對象:

試試看:http://jsfiddle.net/lbstr/JZP2S/

的關鍵是HumanMaker功能。在基本層面上,它需要一個功能並將Human原型添加到它。這可以讓你調用你的功能,從Human獲得所有的屬性,並吃掉它。那就是:

function HumanMaker(f) { 
    var h = Human; 
    h.__proto__ = f.__proto__; 
    f.__proto__ = h; 
    return f; 
} 

你會調用它是這樣的:

var ninja = HumanMaker(function() { 
    alert("I'm a ninja!"); 
}); 

這裏是整個事情:

var Human = { 
    isAlive: true, 
    say: function(what){ 
     alert(what + '!'); 
    }, 
    die: function(){ 
     this.isAlive = false; 
    } 
}; 

function HumanMaker(f) { 
    var h = Human; 
    h.__proto__ = f.__proto__; 
    f.__proto__ = h; 
    return f; 
} 

//These will inherit from it: 
var ninja = HumanMaker(function() { 
    alert("I'm a ninja!"); 
}); 
var samurai = HumanMaker(function(){ 
    alert("I'm a samurai!"); 
}); 

//Now, how can I make ninja and samurai behave like this: 
ninja(); //I'm a ninja! 
samurai(); //I'm a samurai! 
ninja.say('Hello'); //Hello! 


ninja.die(); 
ninja.isAlive == false; 

samurai.isAlive == true;​ 
0

我一直覺得更容易的功能遺傳模式理解:

var human = function(){ 
    var me = {}; 
    var _isAlive = true; 
    Object.defineProperty(me, "isAlive", { 
     get: function() { return _isAlive} 
    }); 

    me.say=function(what){ 
     if(_isAlive) 
      alert(what+'!'); 
     else 
      throw new Error('I am dead!');     
    } 
    me.die=function(){ 
     _isAlive = false;     
    } 
    return me; 
}; 

var person = function(){ 
    var me = human(); 
    return me; 
};   

var ninja = function(){ 
    var me = human(); 
    me.say = function(what){ 
     if(me.isAlive) 
      alert(what+', I am a ninja!'); 
     else 
      throw new Error('I am dead!');   
    }; 
    return me; 
}; 

var myPerson = person(); 
myPerson.say('hi'); 

var myNinja = ninja(); 
myNinja.say('hello'); 

我已經離開這裏演示:http://jsfiddle.net/vtortola/nbpPt/

乾杯。

+0

不錯的代碼,但除非我沒有理解你的代碼,否則我認爲它不能解決問題。忍者不可召喚。人不可擴展。就像,如果忍者是人類的一個實例,並且人類突然採用新的原型方法,忍者也應該擁有該方法,但仍然可以作爲正常函數調用。 – Aria