2016-06-09 69 views
1

我想重寫正在由JavaScript插件創建的函數。我知道如何覆蓋常規的窗口函數,但這是不同的。我不知道如何命名它,但該功能的結構是這樣的:重寫JavaScript(窗口)函數

window.something.function 

我不知道如何重寫。我試過以下內容:

var originalFunction = window.something.function; 
window.something.function = function(parameter) { 
    alert('called'); 
    return originalFunction(parameter); 
} 

但它不工作。

有人知道解決方案嗎?

編輯: 正如我被告知我的問題不清楚,我已經使用插件的實際名稱再次編輯它。

該插件是指被用作:當該正在使用

var myColor = new jscolor(target, options) 

,有一個功能「內部」對象「jscolor」設定目標元素的值時,其將被調用。我想覆蓋該功能來添加一個額外的功能,而無需更改原始的js文件。

代碼:

if (!window.jscolor) { window.jscolor = (function() { 


var jsc = { 
    ..... 
    jscolor : function (targetElement, options) { 
     .... 
     //Function I want to change: 
     this.exportColor = function (flags) { 
      if (!(flags & jsc.leaveValue) && this.valueElement) { 
       var value = this.toString(); 
       if (this.uppercase) { value = value.toUpperCase(); } 
       if (this.hash) { value = '#' + value; } 

       if (jsc.isElementType(this.valueElement, 'input')) { 
        this.valueElement.value = value; 
       } else { 
        this.valueElement.innerHTML = value; 
       } 
      } 
     } 
    } 
}; 

我嘗試至今:

var origJsColor = jscolor.exportColor; 
jscolor.exportColor = function(flags) { 
    console.log('called'); 
    return origJsColor(flags); 
} 

和窗口上方的嘗試。

+0

你可以嘗試運行'window.something.function()'立即在你的函數定義之後,看你定義的函數是否被實現。 –

+0

我更新了我的問題。 @JimmyKo感謝您的回覆。我的函數被調用(這是顯而易見的),但我得到的錯誤「originalFunction」不是一個函數。 – stefan1294

+0

@ T.J.Crowder道歉。我希望現在更清楚。 – stefan1294

回答

1

您顯示的jscolor代碼創建了一個對象,其自身的副本爲exportColor(每個對象都創建一個)。因此,要替換它,必須在實例創建時將其替換爲每個實例。

你可以做,作爲一個一次性的多,你表現的方式,正好與實例,而不是插件功能的工作,並使用Function#call用正確的this叫它:

// Get the instance 
var c = new jscolor(target, options) 

// Update it 
var origExportColor = c.exportColor; 
c.exportColor = function(flags) { 
    console.log('called'); 
    return origExportColor.call(c, flags); // Note the changes on this line 
}; 

或者而不是

return origExportColor.call(c, flags); 

您可以使用

return origExportColor.apply(c, arguments); 

...如果有任何機會只用一個參數來調用函數。 (arguments是包含用來調用該函數的參數的魔法僞陣列。)

如果你想這樣做的所有例如,你可以創建,你可以把一個門面在jscolor前面做,要每一個實例:

var realJscolor = jscolor; 
jscolor = function() { 
    // Call the real function, passing along all the arguments we 
    // get automatically (`arguments` is a magic pseudo-array) 
    var retVal = realJscolor.apply(this, arguments); 

    // If it returned a non-`null` object, we want to use that instead 
    // of `this`; if not, we keep using `this` 
    if (!retVal || typeof retVal !== "object") { 
     retVal = this; 
    } 

    // Slip in our version of exportColor 
    var origExportColor = retVal.exportColor; 
    retVal.exportColor = function(flags) { 
     console.log('called'); 
     // (Maybe use `apply` here instead) 
     return origExportColor.call(retVal, flags); 
    }; 

    // Return the result, in case the real function overrode `this` 
    return retVal; 
}; 
jscolor.prototype = realJscolor.prototype; 

就用jscolor正常:

var c = new jscolor(target, options); 

的原因retVal的是,雖然通常是new表達式的結果是對由new創建的新對象的引用,構造函數可以返回非對象引用,如果是,則new表達式的結果是該對象引用。這就是爲什麼我們檢查realJscolor的返回值。

當然,這意味着全部使用jscolor在頁面上使用全球將現在使用您的更新功能,而不是。如果你不希望出現這種情況,只要用自己的名字,並沒有覆蓋jscolor

var myColor = function() { 
    var retVal = jscolor.apply(this, arguments); 
    // ...and so on... 
    return retVal; 
}; 
myColor.prototype = jscolor.prototype; 

用法:

var c = new myColor(target, options); 
+1

非常感謝你爲這個優秀的解釋。我通過這個答案瞭解了很多。 – stefan1294

0

功能

function a() {alert(this)} // will print `window` obejct 

在窗口範圍限定。也就是說,它是一個方法的窗口。您的more difficult情況來自this與窗口不同的事實,如果您將函數定義爲另一個對象中的方法。

var a = {method: function() {alert(this)}} 

你調用a.method()但是再次看到相同的窗口。您需要將您的功能bind添加到父對象中,以使其成爲競爭方法。