Để cung cấp bức tranh lớn, tôi sẽ giải thích cả ràng buộc động và từ vựng.
động Tên Binding
this
đề cập đến đối tượng phương pháp này được gọi vào. Đây là câu đọc thường xuyên trên SO. Nhưng nó vẫn chỉ là một cụm từ, khá trừu tượng. Có một mẫu mã tương ứng với câu này không?
Có có:
const o = {
m() { console.log(this) }
}
// the important patterns: applying methods
o.m(); // logs o
o["m"](); // logs o
m
là một phương pháp vì nó dựa trên this
. o.m()
hoặc o["m"]()
có nghĩa là m
được áp dụng cho o
. Những mẫu này là bản dịch Javascript cho cụm từ nổi tiếng của chúng tôi.
Còn có một mẫu mã quan trọng là bạn nên chú ý đến:
"use strict";
const o = {
m() { console.log(this) }
}
// m is passed to f as a callback
function f(m) { m() }
// another important pattern: passing methods
f(o.m); // logs undefined
f(o["m"]); // logs undefined
Nó rất giống với mô hình trước đó, chỉ có ngoặc đang thiếu. Nhưng hậu quả là đáng kể: Khi bạn vượt qua m
đến hàm f
, bạn kéo ra m
đối tượng/ngữ cảnh của nó o
. Nó được bật gốc ngay bây giờ và this
là không có gì (chế độ nghiêm ngặt giả định).
từ vựng (hoặc tĩnh) Tên Binding
chức năng mũi tên không có riêng this
/super
/arguments
họ ràng buộc. Họ thừa kế chúng từ phạm vi từ vựng mẹ:
const toString = Object.prototype.toString;
const o = {
foo:() => console.log("window", toString.call(this)),
bar() {
const baz =() => console.log("o", toString.call(this));
baz();
}
}
o.foo() // logs window [object Window]
o.bar() // logs o [object Object]
Ngoài phạm vi toàn cầu (Window
trong các trình duyệt) chỉ có chức năng có thể tạo thành một phạm vi trong Javascript (và {}
khối trong ES2015).Khi chức năng mũi tên o.foo
được gọi là không có chức năng xung quanh mà từ đó baz
có thể kế thừa this
của nó. Do đó nó bắt giữ ràng buộc this
của phạm vi toàn cầu được ràng buộc với đối tượng Window
.
Khi baz
được gọi bởi o.bar
, mũi tên hàm được bao quanh bởi o.bar
(o.bar
tạo cha mẹ phạm vi từ vựng của nó) và có thể kế thừa o.bar
's this
ràng buộc. o.bar
được gọi là o
và do đó this
của nó được ràng buộc với o
.
Nó chỉ đơn giản nắm bắt được giá trị của 'this' từ phạm vi chứa, đối xử với nó như bất kỳ o có biến. – Barmar
Nó chỉ là do đó bạn không cần phải làm kludge của 'var self = this;' và sau đó sử dụng 'self' trong hàm. – Barmar
Trong trường hợp của bạn, không có ngữ cảnh kèm theo, hoặc đó là bối cảnh toàn cục, hoặc ngữ cảnh mô-đun, vì vậy 'this' là bất cứ điều gì trong trường hợp đó, rất có thể là null hoặc window. Nói cách khác, 'this' có giá trị giống như nếu bạn thêm' console.log (this) 'trước khi gán hàm. –