所以,我想每次調用某個函數都要執行一些代碼,這是可行的嗎?事情是,我可以覆蓋現有的函數並添加代碼,但這需要我知道該函數的確切內容......想象一下「庫」的「插件」,並且想要插件,在每次執行代碼時都會調用這個圖書館的特定功能,但是你不想覆蓋原來的圖書館內容......希望我已經清楚了!Javascript:如何在函數調用中執行代碼而不覆蓋該函數?
如果它是可行的,有沒有辦法檢索提交給函數的參數?
所以,我想每次調用某個函數都要執行一些代碼,這是可行的嗎?事情是,我可以覆蓋現有的函數並添加代碼,但這需要我知道該函數的確切內容......想象一下「庫」的「插件」,並且想要插件,在每次執行代碼時都會調用這個圖書館的特定功能,但是你不想覆蓋原來的圖書館內容......希望我已經清楚了!Javascript:如何在函數調用中執行代碼而不覆蓋該函數?
如果它是可行的,有沒有辦法檢索提交給函數的參數?
這絕對是可行的。 JS是一種動態語言,因此您可以使用自己的函數交換存儲在對象中的函數。例如:
var fxnToWrap = obj.someFunction;
obj.someFunction = function() {
console.log("booyah, I'm intercepting every call to obj.someFunction");
fxnToWrap.apply(obj, arguments);
}
這就是我一直在尋找的!不知道.apply(),似乎對我非常有用,謝謝! – Alex 2010-10-27 21:01:04
我很確定倒數第二行應該是fxnToWrap.apply(obj,arguments);因爲要應用的第一個參數設置函數運行的上下文(即將分配給它的內容)。通過將其設置爲obj,func將能夠使用它來訪問該對象的屬性和方法。 – 2010-10-27 23:43:28
@Sid_M你是對的!固定。 – kevingessner 2010-10-28 01:25:25
可能你可以覆蓋對函數的引用?例如:
function add1(x) { return x + 1; }
function log_calls(f, name) {
return function() {
console.log("got a call to", name, "with args", arguments);
return f.apply(null, arguments);
}
}
add1 = log_calls(add1, "add1");
然後調用add1
會是這樣的:
>> x = add1(42)
"got call to add1 with args [42]"
>> x
43
請問我需要什麼,謝謝。 – Alex 2010-10-27 21:01:56
聽起來像一個工作,一個包裝函數給我。
編寫一個調用其他函數的函數,並將你的代碼放在那個(或任何地方)的末尾。然後總是調用你的版本。
適配器模式的排序。 http://en.wikipedia.org/wiki/Adapter_pattern
我相信你可以隱藏原始函數的作用域,並且如果你不能修改調用代碼(不適用於像alert這樣的一些內在函數,但應該適用於庫代碼),那麼你的名字也是一樣的。如果這不是一個選項,請參閱原型是否允許您擴展對象以添加功能。 http://phrogz.net/js/classes/ExtendingJavaScriptObjectsAndClasses.html
//Only add this implementation if one does not already exist.
if (Array.prototype.slice==null) Array.prototype.slice=function(start,end){
if (start<0) start=this.length+start; //'this' refers to the object to which the prototype is applied
if (end==null) end=this.length;
else if (end<0) end=this.length+end;
var newArray=[];
for (var ct=0,i=start;i<end;i++) newArray[ct++]=this[i];
return newArray;
}
對於參數,你也可以讓你的版本採取可選的參數(類似的jQuery/MooTools的),然後看看發生了什麼過去了。
此處可選參數的示例。 http://www.openjs.com/articles/optional_function_arguments.php
function accident() {
for(var i = 0; i < arguments.length; i++) {
alert("This accident was caused by " + arguments[i]);
}
}
編輯以糾正錯誤的評論
指出,這可能會解決你的問題:
function f() {alert("in f");}
var saved_f = f;
var f = function() {
alert("in f2");
saved_f();
}
f();
'saved_f'將指向最後一個'f'定義的函數(導致無限遞歸)。函數聲明是[提升]的主題(http://stackoverflow.com/questions/1710424/referencing-a-javascript-value-before-it-is-declared-can-someone-explain-this/1710509#1710509)。如果你在Firebug的控制檯上嘗試它,似乎可以工作,因爲Mozilla實現定義了一個Function語句,並且控制檯評估的代碼被封裝在一個'with'塊中。在fbug中,嘗試使用匿名函數來封裝上述代碼,例如'(function(){})();' – CMS 2010-10-27 20:47:57
@CMS感謝您的糾正和指導。我已經編輯了這個考慮(並在螢火蟲外測試)。 – 2010-10-27 23:52:31
在[面向方面](http://en.wikipedia.org/wiki/Aspect-oriented_programming)和[功能](http://en.wikipedia.org/wiki/Functional_programming)編程,你問的是[[建議]](http://en.wikipedia.org/wiki/Advice_%28programming%29)。 – outis 2010-10-28 00:06:05