我正在嘗試“Javascript - 權威指南”第 8 章函式中的示例。在第 8.3.4 節“函式呼叫的擴展運算子”中,代碼??是可行的:
function timed(f) {
return function(...args) {
console.log(`Entering function ${f.name}`);
let startTime = Date.now();
try {
return f(...args);
}
finally {
console.log(`Exiting ${f.name} after
${Date.now()-startTime}ms`);
}
};
}
function benchmark(n) {
let sum = 0;
for(let i = 1; i <= n; i ) sum = i;
return sum;
}
timed(benchmark)(1000000);
控制臺輸出是:
Entering function benchmark
Exiting benchmark after 46ms
在第 8.7.4 節“call() 和 apply() 方法”中,函式 timed() 更改為 trace() 并且我無法使代碼作業:
function trace(o, m) {
let original = o[m];
o[m] = function(...args) {
console.log(new Date(), "Entering:", m);
let result = original.apply(this, args);
console.log(new Date(), "Exiting:", m);
return result;
};
}
trace(benchmark)(1000000);
拋出此錯誤:
未捕獲的型別錯誤:trace(...) 不是函式
我嘗試了一些變體,但都不起作用:
benchmark.trace(1000000);
trace.benchmark(1000000);
benchmark.call(trace, 1000000);
obj = {};
trace(obj, benchmark(1000000));
我做了一個檢查:
console.log(typeof trace);
輸出表明 trace() 是一個函式......
有人可以解釋一下 trace() 應該如何與 benchmark() 一起使用嗎?我需要創建新的物件或函式嗎?
這本書只提供了這個提示:
The trace() function defined in the following is similar to the timed() function defined in §8.3.4, but it works for methods instead of functions. It uses the apply() method instead of a spread operator, and by doing that, it is able to invoke the wrapped method with the same arguments and the same this value as the wrapper method:
// Replace the method named m of the object o with a version that logs
// messages before and after invoking the original method.
function trace(o, m) { ...
uj5u.com熱心網友回復:
因此,更新的方法trace應該采用一個物件 ( o) 和該物件 ( ) 上的一個方法m,它旨在用基準測驗功能來裝飾該方法。
以下是如何使用它:
function trace(o, m) {
let original = o[m];
o[m] = function(...args) {
console.log(new Date(), "Entering:", m);
let result = original.apply(this, args);
console.log(new Date(), "Exiting:", m);
return result;
};
}
const myObject = {
benchmark: function(n){
let sum = 0;
for(let i = 1; i <= n; i ) sum = i;
return sum;
}
}
// set up the trace "decorator" so that the method is traced
trace(myObject,"benchmark");
// now call the method and see the trace output
myObject.benchmark(1000000);
我們可以進一步分解這是如何作業的
let original = o[m];
當您傳入一個物件和一個方法名稱時,上面的行會捕獲一個帶有指向該函式的指標的區域變數
o[m] = function(...args) {
....
}
上面的部分用指向新函式的指標替換了物件上的函式
let result = original.apply(this, args);
上面的行使用apply傳入的引數呼叫原始函式(using)。您會注意到 is 的頂部和尾部是console.log您用來查看何時進入和退出方法的。最后,新附加的方法回傳呼叫該original方法的結果。
uj5u.com熱心網友回復:
因為您正在呼叫trace()然后在它后面加上括號,就好像您將正在運行的函式作為函式呼叫一樣。
這是未定義函式的示例:
// trace -> undefined
trace();
// TypeError: trace is not a function
在這個例子中,“trace”是未定義的,它不是一個函式
型別錯誤:trace 不是函式
但是當你呼叫“trace()()”的時候trace是定義的
trace(...) 不是函式
您正在呼叫函式兩次。
你為什么要嘗試呼叫函式函式?
我認為您正在嘗試呼叫函式中的引數:
function trace(o, m) {
let original = o[m];
o[m] = function(...args) {
console.log(new Date(), "Entering:", m);
let result = original.apply(this, args);
console.log(new Date(), "Exiting:", m);
return result;
};
}
trace(benchmark, 1000000);
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/354071.html
標籤:javascript
上一篇:我無法獲得我想要的物件值
