2015-07-03 30 views
-1

在Javascript中,可以通過使用函數構造函數及其「原型」屬性(即「未來實例的父代」)或更近的對象來實現某種繼承.create(),以獲得新的對象。讓一個JavaScript「功能對象」繼承另一個

但是最近我需要爲我的一個項目「覆蓋」Jquery對象(「$」),也就是說,提供了一個類似的函數,它也具有所有的fn/extend/... [inherited ]原始「jQuery」工廠函數的屬性。

目標是默認情況下有一個「$()」函數總是接收「window.parent」作爲第二個參數,以便整個程序修改父框架而不是加載程序的iframe 。

通常我希望能夠做這樣的事情:

var oldJQ = $; 
$ = function (selector) { 
    return oldJQ(selector, window.parent); 
} 
$.__proto__ = oldJQ .__proto__; 

$.extend({...}); // must work 

儘管多次嘗試,我無法得到它的工作,我總是使用「新當了簡單的對象,而不是真正的功能「關鍵字,或繼承不起作用。我找到了替代方法(例如,通過將所有屬性從$複製到我的新函數對象中),但在我看來,這似乎是一種可怕的做事方式。

有什麼辦法可以有一個新的函數對象,作爲父/原型,有原始$對象嗎?

+3

你做了什麼? –

+0

「我總是得到簡單的物體而不是真正的功能」。考慮「函數」不是實際的數據類型。 [這些](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Data_types)是唯一的實際數據類型。這說明了嗎? –

+0

不,這是不可能的。對象只能有一個原型,並且從'Function'繼承的東西不可調用。 ES6代理可能會有所幫助,但這不完全相同。 – Ryan

回答

1

雖然函數是javascript中的對象,但它們不是常規對象。具體來說,它們是繼承被打破的對象。函數不是語言中唯一的這樣的對象,DOM元素也是類似的殘疾人。這就是jQuery實現爲DOM包裝的原因之一,而不是通過繼承來擴展DOM的功能。

幸運的是,雖然OOP在這種情況下不起作用,但我們可以從jQuery本身獲得靈感,並使用FP來做我們需要的。換句話說,儘管你不能繼承函數,但你可以將它包裝在另一個函數中。

例如,如果你需要一個特殊console.log功能,爲您的應用程序,將日誌發送回您的服務器,你可以通過重新定義它覆蓋它:

var log_orig = console.log; 
console.log = function() { 
    ajaxlog([].slice.call(arguments,0).map(function(x){ 
     return JSON.parse(x); 
    }).join(','); 
    log_orig.apply(console,arguments); 
} 

或者,如果你想要的$一個特殊版本,做額外的東西:

function $$() { 
    /* 
    * do extra stuff 
    */ 
    return $.apply(null,arguments); 
} 

或者,如果你想覆蓋$,而是如果包裝:

var old$ = $; 
function $() { 
    /* 
    * do extra stuff 
    */ 
    return old$.apply(null,arguments); 
}