Bối cảnh là một trong những chủ đề luôn tạo ra nhiều nhầm lẫn khi ai đó bắt đầu học javascript và đó là chủ đề mà người phỏng vấn hỏi rất nhiều.
Hãy bắt đầu…
bối cảnh là gì?
Bối cảnh luôn là giá trị của từ khóa
foo.apply[ context,[param1, param2, param3]];
1 tham chiếu đến đối tượng “sở hữu” mã hiện đang thực thi hoặc chức năng mà nó được xem xétChúng tôi biết rằng
foo.apply[ context,[param1, param2, param3]];
2 là một đối tượng toàn cầu trong trình duyệt, vì vậy nếu chúng tôi nhập foo.apply[ context,[param1, param2, param3]];
1 vào bảng điều khiển và nó sẽ trả về đối tượng cửa sổ, điều này sẽ xảy ratrong nút. js CLI nếu bạn thử làm như trên, bạn sẽ nhận được một đối tượng có tất cả các chức năng được sử dụng trên toàn cầu như
foo.apply[ context,[param1, param2, param3]];
4, foo.apply[ context,[param1, param2, param3]];
0, v.v. [Thử một lần]Ghi chú. Giá trị của từ khóa
foo.apply[ context,[param1, param2, param3]];
1 phụ thuộc vào đối tượng mà hàm được chạy/gọi/ngồi trên đó. Do đó, từ khóafoo.apply[ context,[param1, param2, param3]];
1 có các giá trị khác nhau tùy thuộc vào nơi nó được sử dụngGhi chú. Từ bây giờ, điều này và bối cảnh được sử dụng thay thế cho nhau
Bối cảnh - trên toàn cầu và bên trong một chức năng
cái này ở cấp độ toàn cầu được gọi trên đối tượng toàn cầu
foo.apply[ context,[param1, param2, param3]];
3 là chức năng được xác định ở cấp độ toàn cầu và được gọi trên đối tượng cấp độ toàn cầu i. e foo.apply[ context,[param1, param2, param3]];
2vì vậy gọi foo.apply[ context,[param1, param2, param3]];
3và foo.apply[ context,[param1, param2, param3]];
6là như nhau. Do đó bối cảnh là một đối tượng foo.apply[ context,[param1, param2, param3]];
2chức năng bên trong này được gọi trên đối tượng chức năng ở cấp độ toàn cầu
Trong khi đó, nếu chúng tôi thực hiện
foo.apply[ context,[param1, param2, param3]];
8 ở cấp độ toàn cầu thì sẽ nhận được foo.apply[ context,[param1, param2, param3]];
1 là đối tượng foo.apply[ context,[param1, param2, param3]];
3Ghi chú. Toán tử
// use of bind1 tạo một thể hiện của một đối tượng. Bối cảnh của chức năng sẽ được đặt thành phiên bản đã tạo của một đối tượng
exec: function [] {
this.f2[function [] {
this.f1[];
}.bind[this]];
}// use of arrow function
exec: function [] {
this.f2[[] => {
this.f1[];
}];
}// another way not recommended though
exec: function [] {
var that = this;
this.f2[[] => {
that.f1[];
}];
}
Bối cảnh - dưới chức năng cấp 2
Bối cảnh — khi chức năng được xác định trên toàn cầu và được sử dụng dưới một đối tượng [Ràng buộc ngầm định]
Ghi chú. Từ trên, chúng tôi nhận được giá trị của từ khóa
foo.apply[ context,[param1, param2, param3]];
1 phụ thuộc vào chức năng được gọi khi không phải nơi chức năng được xác định
Ngữ cảnh hoạt động như thế nào trong 'sử dụng nghiêm ngặt'?
Khi sử dụng
// use of bind3 trong một chức năng, bối cảnh tôi. e từ khóa này hoạt động khác. Bối cảnh vẫn là bất cứ điều gì nó được gọi
exec: function [] {
this.f2[function [] {
this.f1[];
}.bind[this]];
}// use of arrow function
exec: function [] {
this.f2[[] => {
this.f1[];
}];
}// another way not recommended though
exec: function [] {
var that = this;
this.f2[[] => {
that.f1[];
}];
}
Ghi chú. Toàn bộ chương trình của chúng ta có lẽ nên là
// use of bind4 hoặc
exec: function [] {
this.f2[function [] {
this.f1[];
}.bind[this]];
}// use of arrow function
exec: function [] {
this.f2[[] => {
this.f1[];
}];
}// another way not recommended though
exec: function [] {
var that = this;
this.f2[[] => {
that.f1[];
}];
}// use of bind5. Tuy nhiên, đôi khi bạn bao gồm một thư viện của bên thứ ba có tính nghiêm ngặt khác với mã của riêng bạn, vì vậy phải cẩn thận với các chi tiết tương thích tinh vi này
exec: function [] {
this.f2[function [] {
this.f1[];
}.bind[this]];
}// use of arrow function
exec: function [] {
this.f2[[] => {
this.f1[];
}];
}// another way not recommended though
exec: function [] {
var that = this;
this.f2[[] => {
that.f1[];
}];
}
Ngữ cảnh hoạt động như thế nào trong chức năng mũi tên?
Các chức năng mũi tên hoạt động khác với các chức năng thông thường về ngữ cảnh.
foo.apply[ context,[param1, param2, param3]];
1sẽ luôn đề cập đến phạm vi từ vựng [đọc ở đây về phạm vi], tôi. e foo.apply[ context,[param1, param2, param3]];
1 giữ nguyên giá trị của ngữ cảnh từ vựng kèm theoTrong mã toàn cầu, nó sẽ được đặt thành đối tượng toàn cầu, do đó chúng tôi nhận được trên true
Bối cảnh hoạt động như thế nào trên chuỗi nguyên mẫu của đối tượng?
Bối cảnh tuân theo cùng một quy tắc, tôi. e. nếu hàm nằm trên chuỗi nguyên mẫu của một đối tượng, thì
foo.apply[ context,[param1, param2, param3]];
1 đề cập đến đối tượng mà phương thức được gọi trên đóNếu chúng tôi gọi
// use of bind9 sẽ nhận được
exec: function [] {
this.f2[function [] {
this.f1[];
}.bind[this]];
}// use of arrow function
exec: function [] {
this.f2[[] => {
this.f1[];
}];
}// another way not recommended though
exec: function [] {
var that = this;
this.f2[[] => {
that.f1[];
}];
}
foo.apply[ context,[param1, param2, param3]];
20 và nếu foo.apply[ context,[param1, param2, param3]];
21 được gọi trên foo.apply[ context,[param1, param2, param3]];
22 được tạo từ foo.apply[ context,[param1, param2, param3]];
23 đã xác định foo.apply[ context,[param1, param2, param3]];
24 thì nó sẽ trả về giá trị do đó 10Bối cảnh hoạt động như thế nào trong trình xử lý sự kiện?
Bối cảnh trong trường hợp trình xử lý sự kiện đề cập đến phần tử đã nhận sự kiện
Ở đây chúng ta đã thêm một sự kiện click jquery vào thẻ body của DOM, và chúng ta có thể thấy rằng ngữ cảnh trả về phần tử body
Bối cảnh hoạt động như thế nào trong bối cảnh thực thi?
Nếu bạn không biết bối cảnh thực thi là gì [đọc tại đây]. Nói tóm lại, bối cảnh thực thi là 'môi trường' hoặc phạm vi trong đó một chức năng thực thi trong. Mỗi khi một hàm được gọi, một
foo.apply[ context,[param1, param2, param3]];
25 mới được tạo. Mỗi cuộc gọi đến một foo.apply[ context,[param1, param2, param3]];
25 có 2 giai đoạn- Tạo - khi chức năng được gọi
- Kích hoạt — khi chức năng được thực thi
Giá trị của
foo.apply[ context,[param1, param2, param3]];
1 được xác định ở giai đoạn tạo, không phải ở thời điểm thực thi. Tuy nhiên, quy tắc xác định foo.apply[ context,[param1, param2, param3]];
1 vẫn giữ nguyênBối cảnh khác với phạm vi như thế nào?
Phạm vi và ngữ cảnh hoàn toàn là một khái niệm khác nhưng thường được nhà phát triển sắp tới sử dụng thay thế cho nhau
Phạm vi là khả năng truy cập của các biến, hàm hoặc đối tượng trong một số phần cụ thể của mã của bạn trong thời gian chạy. Đọc thêm ở đây về phạm vi
Mọi lời gọi hàm đều có cả phạm vi và ngữ cảnh được liên kết với nó
Làm thế nào để thay đổi bối cảnh một cách rõ ràng?
Chúng ta có thể tự động thay đổi ngữ cảnh của bất kỳ phương pháp nào bằng cách sử dụng phương pháp
foo.apply[ context,[param1, param2, param3]];
29 ,foo.apply[ context,[param1, param2, param3]];
00và foo.apply[ context,[param1, param2, param3]];
01Cuộc gọi - Đối số đầu tiên mà
foo.apply[ context,[param1, param2, param3]];
02 đưa vào là ngữ cảnh bạn muốn sử dụng. Sau đó, bạn có thể chuyển vào bất kỳ số lượng giá trị được phân tách bằng dấu phẩy nàofoo.apply[ context,[param1, param2, param3]];
3Áp dụng — Điều này giống như
foo.apply[ context,[param1, param2, param3]];
02 nhưng khác ở chỗ không. tranh luận. Áp dụng chỉ hỗ trợ 2 đối số, ngữ cảnh và mảng giá trịfoo.apply[ context,[param1, param2, param3]];
Ràng buộc — Nó trả về một hàm mới được liên kết vĩnh viễn với đối số đầu tiên của
foo.apply[ context,[param1, param2, param3]];
04 bất kể hàm đó đang được sử dụng như thế nào. foo.apply[ context,[param1, param2, param3]];
04 không gọi hàm liên kết ngay lập tức, thay vào đó nó trả về một hàm mới mà chúng ta có thể chạy sauTại sao chúng ta cần thay đổi bối cảnh một cách rõ ràng?
- Khi chúng ta cần gọi một hàm được xác định bên trong một đối tượng, hãy nói
foo.apply[ context,[param1, param2, param3]];
24nhưng trên các đối tượng khác, hãy nóifoo.apply[ context,[param1, param2, param3]];
07, chúng ta có thể sử dụng các phương thức rõ ràng để làm như vậy, để tăng khả năng sử dụng lại
2. Currying và ứng dụng một phần là một phần khác trong đó thay đổi rõ ràng trong ngữ cảnh được sử dụng
3. Để thực hiện các chức năng tiện ích như
4. Kế thừa là một nơi khác có thể sử dụng thay đổi ngữ cảnh rõ ràng
Bình luận bên dưới nếu bạn biết thêm lý do. ]
Các trường hợp chúng ta cần quan tâm đến bối cảnh là gì?
Chúng tôi có thể mất bối cảnh tôi. e nhận được giá trị
foo.apply[ context,[param1, param2, param3]];
20 cho foo.apply[ context,[param1, param2, param3]];
1in1. Hàm lồng nhau
Chúng ta cần giữ ngữ cảnh của đối tượng
foo.apply[ context,[param1, param2, param3]];
23 được tham chiếu khi hàm gọi lại được gọi, ở trên, điều đó không xảy ra và chúng ta gặp lỗiChúng ta có thể loại bỏ lỗi trên bằng cách thay thế mã
foo.apply[ context,[param1, param2, param3]];
21 bằng bên dưới// use of bind
exec: function [] {
this.f2[function [] {
this.f1[];
}.bind[this]];
}// use of arrow function
exec: function [] {
this.f2[[] => {
this.f1[];
}];
}// another way not recommended though
exec: function [] {
var that = this;
this.f2[[] => {
that.f1[];
}];
}
2. Phương thức gọi lại
foo.apply[ context,[param1, param2, param3]];
2Ở trên sẽ trả về
foo.apply[ context,[param1, param2, param3]];
22, hãy suy nghĩ một chút tại sao? foo.apply[ context,[param1, param2, param3]];
0và,
foo.apply[ context,[param1, param2, param3]];
23 có chức năng foo.apply[ context,[param1, param2, param3]];
24, tách biệt với đối tượng foo.apply[ context,[param1, param2, param3]];
23Giải pháp là
foo.apply[ context,[param1, param2, param3]];
2Ghi chú
1. Tạo một "tham chiếu phương thức ràng buộc" yêu cầu hàm bao bọc ẩn danh và chi phí gọi. Trong các tình huống cụ thể, tận dụng các lần đóng cửa có thể là một giải pháp thay thế tốt hơn
2. Bất kỳ loại tham chiếu hàm nào [gán dưới dạng giá trị, truyền dưới dạng đối số] đều làm mất ràng buộc ban đầu của hàm
Vui lòng cân nhắc nhập email của bạn tại đây nếu bạn muốn được thêm vào danh sách email của tôi và theo dõi tôi trên phương tiện để đọc thêm bài viết về javascript và trên github để xem mã điên rồ của tôi. Nếu có gì chưa rõ hoặc muốn chỉ ra điều gì, hãy comment xuống bên dưới