2013-01-11 42 views
2

當我在JavaScript中編寫函數包裝器(例如:throttledebounce函數)時,我希望能夠檢查'裝飾'函數,並且仍然能夠知道底層函數是什麼。取throttle的實現爲例:在JavaScript中重寫function.toString時應該擔心嗎?

function throttle(fn, time) { 
    var handle; 

    var execute = function() { 
    handle = null; 
    fn.apply(this, arguments); 
    }; 

    var throttled = function() { 
    if(!handle) { 
     handle = setTimeout(execute.bind(this), time); 
    } 
    }; 

    throttled.toString = function() { 
    return fn.toString() + "\n// throttled to " + time + "ms"; 
    }; 

    return throttled; 
} 

var makeAjax = throttle(function(callback) { 
    $.getJSON("/path", callback); 
}, 500); 

console.log(makeAjax); 

console.log來電顯示:

function (callback) { 
    $.getJSON("/path", callback); 
} 
// throttled to 500ms 

由於throttle用戶我更關心了一大堆關於我把它比它的內部throttled功能。

但是,在重寫原生函數時,我總是感到有點不安。在執行此操作時是否存在任何我應該擔心的合規性和/或性能問題?

+0

隱式轉換可能是一個問題。但是你可能不會有隱式投射函數的情況。 –

+2

任何會調用'fn.toString()'的東西都是用於日誌記錄或動態重新編譯,所以我認爲你會爲此罰款。特別是因爲你不覆蓋'Function.prototype.toString'。 – Esailija

+0

@Esailija你是什麼意思動態重新編譯? –

回答

3

在Mozilla開發人員小組中,他們更多地談到重寫toString()。 https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/toString

我覺得這可能是一個可能的問題,下面是一個創建自動化單元測試(我的經驗僅限於NUnit的硒),您可能不能夠使用專用的ToString(),也可能導致不穩定的測試結果如何?調試也可能是一個問題!

要覆蓋其他具有方法的本地js函數,您可能還需要手動擴展所有方法以替換被覆蓋的內容。

阿迪·奧斯馬尼討論這進一步在他的著作「學習JavaScript設計模式」,http://addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript

+0

我們的目標是協助調試,因爲在處理裝飾的時候通常無法達到原始功能......我想可能會在'throttle'nastier中發現錯誤以便找到。我不明白你在第三段中的意思,你能擴展一下還是舉個例子?謝謝! –

+0

該mdn文章是關於'Object.prototype.toString',而不是['Function.prototype.toString'](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/toString )。 toString對象在這裏根本不相關。 – Esailija

+0

@Esailija默認情況下,javascript中的函數是對象。所以當你創建一個函數時,它會自動繼承Object屬性。爲進一步閱讀檢查https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function – Eric

相關問題