我正在嘗試創建一個函數擴展來消除任何函數(如果該函數在快速連續中被多次調用,只執行一次,並最優地返回一個緩存的值)。如何訪問擁有Function.prototype擴展的函數?
我打算在UI框架中使用它,但我希望它是可移植的。我到目前爲止的代碼如下:
Function.prototype.debounce = function()
{
var originalFunction = this; //this should be 'clickButton' in the example implementation
var originalArguments = arguments;
function debouncedFunction()
{
var originalContext = this;
return originalFunction.apply(originalContext,originalArguments)
}
if(this.__DEBOUNCEDVALUE === undefined)
{
this.__DEBOUNCEDVALUE = debouncedFunction();
if(this.__DEBOUNCEDVALUE === undefined)
this.__DEBOUNCEDVALUE = null;
setTimeout(function(){originalFunction.__DEBOUNCEDVALUE = undefined},1000);
}
return this;
}
接下來,我定義了一個通用的功能,「clickButton」,它看起來像這樣:
function clickButton()
{
document.getElementById('log').innerHTML += "<br/>Clicked "+arguments[1];
return "some value";
}
當我打電話clickButton.debounce(3,4)
,它的工作原理。它每秒只記錄一次文檔,但每次調用時都會返回。
但是,當我通過監聽器(buttons[i].addEventListener('click',clickButton.debounce)
)調用它時,originalFunction
變量設置爲按鈕,而不是該函數。不是一個大驚喜。在這個例子中,我如何從debounce中得到對clickButton
的引用?
編輯: 我試過切換到使用defineProperty,它允許我在訪問時保存上下文和函數。不幸的是,這在所有情況下都不起作用(將它放入Sencha Touch中的tap處理程序會導致在Window範圍內調用一個函數)。這更接近,但仍然不可接受。
Object.defineProperty(Function.prototype,'debounce',{get: function()
{
var originalFunction = this;
var execute = function()
{
if(originalFunction.__DEBOUNCEDVALUE === undefined)
{
originalFunction.__DEBOUNCEDVALUE = originalFunction.apply(this,arguments);
if(originalFunction.__DEBOUNCEDVALUE === undefined)
originalFunction.__DEBOUNCEDVALUE = null;
setTimeout(function()
{
originalFunction.__DEBOUNCEDVALUE = undefined;
console.log("Reset");
},5000);
}
else
console.log("Return cached value");
return originalFunction.__DEBOUNCEDVALUE;
}
return execute;
}});