2013-07-25 32 views
5

win trỏ đến window. NS là một không gian tên tạm thời cho bài đăng này. Tôi nghĩ rằng nếu tôi muốn truy cập vào setTimeout, tôi chỉ có thể sao chép trên các tài liệu tham khảo chức năng như vậy:Làm thế nào các tham chiếu hàm có thể được thực hiện đúng (1)?

NS.setTimeout = win.setTimeout; 

Tuy nhiên, thực thi sẽ ném ra một lỗi:

NS_ERROR_XPC_BAD_OP_ON_WN_PROTO: Illegal operation on WrappedNative prototype object @ ... 

Để khắc phục lỗi này, tôi chỉ đã làm:

NS.setTimeout = function (arg1, arg2) { 
    return win.setTimeout(arg1, arg2); 
}; 

Tuy nhiên, tôi không biết tại sao điều này khắc phục được. Tôi không biết cơ chế ngôn ngữ nào đang gây ra hành vi này.

+0

Bài tập của chính nó sẽ không gây ra lỗi như vậy. Tôi nghĩ câu hỏi của bạn là sai lạc. Bạn phải có nghĩa là ** gọi ** giá trị được chỉ định làm tăng lỗi. –

+3

Tôi không hiểu. setTimeout() có sẵn trên toàn cầu, phải không? Tại sao làm tất cả điều này? – Paul

+0

Đồng ý với @Paul: D – Sebas

Trả lời

0

Điều này đã khắc phục được sự cố b.c. bạn đang thay đổi đối tượng gọi lại thành bản gốc khi bạn gọi nó.

return win.setTimeout(arg1, arg2); 

sẽ đặt bối cảnh (hoặc điều này) trở lại cửa sổ cần thiết. Các câu trả lời khác tương tự trong thực tế là chúng thay đổi bối cảnh thành giá trị chính xác bằng cách sử dụng bind đến apply.

+0

Bạn là một nhà thơ và một học giả thưa ngài! –

+0

Tôi cố gắng hết sức mình. –

8

gì bạn muốn điều này là:

NS.setTimeout = win.setTimeout.bind(win); 

hoặc những gì bạn đã làm, nếu bạn muốn để tương thích với IE8.

setTimeout, giống như nhiều window chức năng, nhu cầu người nhận (this) là window.

Một giải pháp tương thích IE8, thanh lịch hơn trong quan điểm của tôi hơn của bạn (vì nó không sử dụng thực tế bạn biết số lượng các đối số cần thiết bởi setTimeout), sẽ là

NS.setTimeout = function(){ 
    return win.setTimeout.apply(win, arguments); 
}; 
+1

Đừng quên trả lại kết quả! – Bergi

+0

@Bergi đúng! Đã chỉnh sửa. –

4

Lý do tại sao bạn có thể không làm điều đó là vì, khi xác định, bạn đang thay đổi ngữ cảnh cuộc gọi của setTimeout, điều này không được phép.
Cũng không được phép cho setInterval và nhiều đối tượng/chức năng gốc khác. Một lần nữa: một nguyên tắc chung: nếu bạn không sở hữu đối tượng này, đừng chạm vào nó. Kể từ khi chức năng là các đối tượng trong JS, quy tắc áp dụng đối với họ, quá

check the specs on the global object và tài sản/funcitons BUILTIN của nó:

There are certain built-in objects available whenever an ECMAScript program begins execution. One, the global object, is part of the lexical environment of the executing program. Others are accessible as initial properties of the global object.

Và vân vân. Nhưng the lexical environment là khá đáng kể. Bằng cách gán một tham chiếu đến hàm ở nơi khác, bạn cũng có thể che giấu một phần của môi trường từ vựng, hoặc phơi bày quá nhiều môi trường toàn cục (ví dụ như các mashup).

+1

điều này không chỉ dành riêng cho setTimeout. Tôi đã nhìn thấy vấn đề này khi sao chép trên 'console.log' là tốt. +1. –

+0

@ Bill-TheButcher-Cắt: Chỉnh sửa được thực hiện cho câu trả lời của tôi, nhưng kể từ khi dystroy đã ở đây đầu tiên, tốt nhất chấp nhận câu trả lời của mình –

+1

Phần "* the this this problem *" mà bạn liên kết không liên quan gì đến vấn đề OP. – Bergi

Các vấn đề liên quan