Gần đây tôi đã nhìn vào mã của firebugs console.log
bằng cách gọi console.log.toString()
và nhận điều này:Function.apply vs Function.prototype.apply
function() { return Function.apply.call(x.log, x, arguments); }
Chừng nào tôi hiểu điều này gây ra Function.apply
được gọi với this
của nó đề cập đến x.log
và các đối số là x
và arguments
. Vì các chức năng của chính cuộc gọi Function.apply
này sẽ dẫn đến x.log
được gọi với số this
tham chiếu đến x
và arguments
làm đối số của nó.
Điều gì dẫn tôi đến câu hỏi của mình: Có lý do nào để gọi Function.apply
theo cách này thay vì chỉ sử dụng Function.prototype.apply
? Hay nói cách khác, có sự khác biệt nào giữa các bên trên và return x.log.apply(x, arguments)
không?
Edit: Vì nó là mã nguồn mở Tôi đã xem nhanh tại sourcecode firebug và tìm thấy nơi này được tạo ra (consoleInjector.js, dòng 73):
// Construct a script string that defines a function. This function returns
// an object that wraps every 'console' method. This function will be evaluated
// in a window content sandbox and return a wrapper for the 'console' object.
// Note that this wrapper appends an additional frame that shouldn't be displayed
// to the user.
var expr = "(function(x) { return {\n";
for (var p in console)
{
var func = console[p];
if (typeof(func) == "function")
{
expr += p + ": function() { return Function.apply.call(x." + p +
", x, arguments); },\n";
}
}
expr += "};})";
// Evaluate the function in the window sandbox/scope and execute. The return value
// is a wrapper for the 'console' object.
var sandbox = Cu.Sandbox(win);
var getConsoleWrapper = Cu.evalInSandbox(expr, sandbox);
win.wrappedJSObject.console = getConsoleWrapper(console);
Tôi gần như chắc chắn bây giờ mà điều này có liên quan gì đó với Function
để ở trong một phạm vi khác, đó là những gì tôi đã nói trong nhận xét đầu tiên của tôi về câu trả lời của câu trả lời của tôi, nhưng tôi vẫn chưa hiểu hết. Tôi có thể làm một chút nghiên cứu thêm về điều đó.
Tôi tò mò là tại sao mã không chỉ sử dụng kết quả của 'Cu.evalInSandbox (" Function ", sandbox)' trong cách tiếp cận đóng cửa tiêu chuẩn (vì các đối tượng hàm dường như được trả về), nhưng dường như ở đó là một lý do .. thực sự, điều đó không tạo ra nhiều từ một trong hai, vì 'Hàm' nên * không * được đóng lại; trừ khi có nhiều ma thuật trong 'evalInSandbox' .. –