Trong JavaScript, this
trong một cuộc gọi chức năng được xác định bởi cách chức năng được gọi (đối với các chức năng bình thường, xem * bên dưới). Nếu được gọi là một phần của biểu thức truy xuất thuộc tính đối tượng (ví dụ: foo.bar()
gọi bar()
như một phần của hoạt động truy xuất thuộc tính nhận được từ foo
), this
được đặt thành đối tượng mà thuộc tính xuất phát trong khi gọi hàm.
Giả sử bạn muốn có dạng ngắn hơn là console.log
, như f
. Bạn có thể làm điều này:
var f = console.log; // <== Suspect!
... nhưng nếu log
chức năng dựa vào this
đề cập đến đối tượng console
trong suốt cuộc gọi, sau đó gọi f("Message here")
sẽ không làm việc, bởi vì this
sẽ không đề cập đến console
.
Function#bind
chỉ dành cho trường hợp đó: Nó cho phép bạn tạo một hàm mới, khi được gọi, sẽ gọi hàm gốc với this
được đặt thành giá trị bạn cung cấp. Vì vậy,
var f = console.log.bind(console); // Still suspect, for a different reason
... nên, về mặt lý thuyết, cung cấp cho bạn một chức năng, f
, mà bạn có thể gọi để đăng nhập vào giao diện điều khiển.
Trừ: chức năng chủ cung cấp như console.log
(và alert
và getElementById
) không phải là "thực" JavaScript chức năng (mặc dù trên các trình duyệt hiện đại họ có xu hướng, hoặc ít nhất là rất gần), và aren không bắt buộc phải có tất cả các tính năng của họ, inculding bind
. Vì vậy, nếu bạn gặp lỗi trên dòng đó, có thể là công cụ bạn đang sử dụng dòng đó không hỗ trợ bind
trên chức năng console.log
.
Vậy "chức năng do máy chủ cung cấp" là gì? Bất kỳ hàm nào không được xác định rõ ràng trong đặc điểm kỹ thuật như là một phần của JavaScript, ngôn ngữ. Một lần nữa, trên trình duyệt có chức năng liên quan đến trình duyệt như alert
hoặc console.log
và các chức năng như vậy.
tôi có thể nghĩ ra hai lý do khiến dòng có thể đem lại cho bạn rắc rối:
Trên đây: Bạn đang sử dụng một công cụ JavaScript mà không làm cho console.log
một chức năng thực sự.
Bạn đang sử dụng dòng ở trên trên IE với Công cụ tìm kiếm đã đóng. Trên IE khi các công cụ dev không mở, đối tượng console
không được xác định và do đó dòng đó sẽ ném một số ReferenceError
.
Nếu mục tiêu cuối cùng là để có được một chức năng bạn có thể gọi điện thoại, nói f("Message here")
, cho console.log
, dưới đây là cách bạn có thể làm điều đó đối phó với cả # 1 và # 2 ở trên:
function f(item) {
if (typeof console != "undefined" && console.log) {
console.log(item);
}
}
Đó chỉ cho phép bạn cung cấp một mục, trong khi console.log
cho phép bạn cung cấp nhiều mục (console.log("this", "that", "and the other")
), nhưng nếu console.log
có thể không phải là hàm JavaScript thực, thì có thể không có Function#apply
.
Bây giờ, nếu bạn không quan tâm về việc các cùng đầu ra bạn muốn nhận được từ console.log("this", "that", "and the other")
chừng nào bạn có thể nhìn thấy những gì ở đó, chỉ cần sử dụng console.log(arguments);
(arguments
là được xây dựng trong nhận dạng cho tất cả các đối số được truyền vào một hàm). Nhưng nếu bạn muốn sao chép kết quả chính xác, bạn sẽ thực hiện một việc như sau:
function f() {
var a = arguments;
if (typeof console != "undefined" && console.log) {
if (console.log.apply) {
// It has Function#apply, use it
console.log.apply(console, arguments);
} else {
// Ugh, no Function#apply
switch (a.length) {
case 0: console.log(); break;
case 1: console.log(a[0]); break;
case 2: console.log(a[0], a[1]); break;
case 3: console.log(a[0], a[1], a[2]); break;
case 4: console.log(a[0], a[1], a[2], a[3]); break;
case 5: console.log(a[0], a[1], a[2], a[3], a[4]); break;
default:
throw "f() only supports up to 5 arguments";
}
}
}
}
... và điều đó thật xấu xí.
* ES5 thêm ràng buộc chức năng, đó là chức năng mà có giá trị this
của họ gắn liền với họ thông qua ràng buộc:
// Normal function
function foo() {
console.log(this.name);
}
// Create a bound function:
var f = foo.bind(someObject);
Nó không quan trọng như thế nào bạn gọi f
, nó sẽ gọi foo
với this
được đặt thành someObject
.
* ES2015 (aka ES6) đã thêm chức năng mũi tên. Với các chức năng mũi tên, this
là không được đặt theo cách gọi hàm; thay vào đó, chức năng thừa hưởng this
từ bối cảnh trong đó nó đã được tạo ra:
// Whatever `this` is here...
var f =() => { // <== Creates an arrow function
// Is what `this` will be here
};
chức năng mũi tên thực sự tiện dụng khi bạn đang làm một cái gì đó giống như Array#forEach
trong vòng một phương pháp đối tượng:
this.counter = 0;
this.someArray.forEach(entry => {
if (entry.has(/* some relevant something */)) {
++this.counter;
}
});
https://developer.mozilla.org/ en-US/docs/Web/JavaScript/Tham chiếu/Global_Objects/Chức năng/liên kết – zerkms
http://stackoverflow.com/questions/20723602/bind-event-handler-to-console-log-javascript-event –
Function.bind () là thiếu từ IE8, nhưng nên làm việc tốt trong br thực owsers. đăng mã bị hỏng nếu nghi ngờ. – dandavis