đang đơn giản hóa này thể hiện một vấn đề tương tự:
var x = Function.call.call;
x(alert);
Trong trường hợp này, một lần Function.call.call
được gọi, nó sẽ không nhớ những bối cảnh mà từ đó nó có nguồn gốc (ví dụ: Function.call
). Để tiết kiệm bối cảnh này, bạn có thể sử dụng này
unholy xây dựng
lừa:
Function.call.bind(Function.call)
Nó trả về một chức năng mới trong đó bối cảnh Function.call
là ràng buộc để chính nó, do đó tiết kiệm bối cảnh. Bạn có thể lưu cụm từ này trong một biến mới:
var callFn = Function.call.bind(Function.call);
Bây giờ, callFn(alert)
giống hệt với alert.call()
. Lưu ý rằng bất kỳ đối số bổ sung nào cũng sẽ được chuyển theo đúng như vậy, vì vậy, callFn(alert, window)
sẽ gọi alert.call(window)
. Hiểu hành vi này rất quan trọng trong các tình huống khi callFn
được gọi là một phần của cuộc gọi lại như Array.forEach
, nhờ đó ba đối số được chuyển trong mỗi lần lặp.
fns.forEach(callFn);
Trong trường hợp của bạn, không ai trong số các chức năng bên trong fns
đang sử dụng các đối số được thông qua, nhưng đằng sau hậu trường chúng được gọi như thế này:
fns[0].call(0, fns)
Vì vậy this
bằng chỉ số của phần tử (tức là Number(0)
) và arguments[0]
tương đương với mảng chức năng. Người quan sát quan tâm có thể nhận thấy rằng giá trị của phần tử rơi vào giữa các vết nứt, mặc dù nó vẫn có thể được tham chiếu bằng cách sử dụng arguments[0][this]
hoặc, cách khác, arguments.callee
(không được chấp nhận).
Nguồn
2013-04-10 10:48:26
Bingo, đúng vậy! Cảm ơn nhiều. – georg
Theo dõi tốt về các đối số, nhưng tại sao 'callee'? Có gì sai với chỉ đơn giản là 'đối số [0] [này]'? – georg
@ thg435 Đó là một điểm tốt; mà sẽ làm việc trong trường hợp này :) cập nhật, với cảm ơn! –