2012-02-24 69 views
3

是否有可能使我自己的函數在JavaScript中實現?使用__invoke魔術方法讓javascript對象像php對象一樣?是否有可能從JavaScript Function對象繼承?

A = function(){}; 
    A.prototype = new Function(); 

    var a = new A(); 
    alert(a instanceof Function); // true 
    a(); // exception 

不能回答我的問題...有一個答案:

對不起everebody,但我已經找到了好的方法對我的工作(我是在幾個步驟從答案離開時發佈題)。我不會刪除問題,希望有人會花更少的時間,然後我。

A = function() 
    { 
    var f = function() { alert('f called') }; 
    f.__proto__ = A.prototype; 
    return f; 
    }; 

    A.prototype = Function(); 
    A.prototype.method = function() { alert('method called') }; 

    var a = new A(); 
    alert(a instanceof Function); // true 
    alert(a instanceof A); // true 
    a(); // f called 
    a.method(); // method called 

如果是新手的問題,請給我發email,我會刪除它。謝謝!

+0

什麼?簡單地將'a'作爲一個具有所需行爲的函數缺乏什麼? – davin 2012-02-24 19:26:57

+0

閱讀http://www.crockford.com/javascript/inheritance.html – 2012-02-24 19:28:51

+0

@Leo您的解決方案在IE中不起作用,因爲該瀏覽器沒有實現'__proto__'。另外,請注意'__proto__'是非標準的,它被**棄用**,所以它可能不是一個好主意,依靠它... – 2012-02-24 19:42:22

回答

0

這不是很好嗎?不幸的是,沒有好的辦法。

正如您可能已經注意到的那樣,問題是將函數設置爲構造函數的prototype,然後使用new結果調用構造函數,而不是可調用的函數對象。

有一種可能的半解決方法,具體取決於您的需要。這是一個有趣的技巧,但可能不是真實世界使用的好主意。您可以創建一個iframe,並從iframe的窗口中獲取Function。現在你有一個「副本」Function,你可以做任何你想做的事情,而不會弄髒你的「真實」Function功能。

var frame = document.createElement('iframe'); 
frame.id = frame.name = 'hacks'; 
frame.style.zIndex = '-1'; 
document.appendChild(frame); 
var MyFunction = frames['hacks'].Function; 
// add stuff to MyFunction and MyFunction.prototype 
0

如何:

function MyFunction (f) { 
    _.extend(f, MyFunction.prototype); 
    return f; 
}; 

MyFunction.prototype.method = function() { 
    alert('method called'); 
}; 

var func = MyFunction(function() { 
    alert('function called'); 
}); 

現場演示:

var func = MyFunction(function() {...}); 
http://jsfiddle.net/nZczW/

所以,您可以通過它們傳遞給您的自定義函數的構造函數創建自定義函數

方法定義(通常)在構造函數的原型上:

MyFunction.prototype.foo = function() {...}; 

在構造函數中,方法直接賦給函數本身。 (我用underscore.js的_.extend())。所以,你的功能仍然直接從Function.prototype繼承。

您當然可以簡化這個模式:

var methods = { /* hash of methods */ }; 

var func = _.extend(function() { ... }, methods);