Hiểu JavaScript từ khóa này
Nếu bạn muốn trở thành một lập trình viên, bất kể bạn chọn lĩnh vực cụ thể nào, bạn gần như chắc chắn sẽ cần phải sử dụng JavaScript. Nó đã phát triển từ những khởi đầu khiêm tốn thành một cường quốc thực sự. Nó hiện bao gồm giao diện người dùng, phụ trợ, thiết bị di động, trò chơi, ứng dụng máy tính để bàn và thậm chí cả học máy!
Bây giờ, trước khi bạn trở thành một chuyên gia JavaScript và phân nhánh, bạn phải học các nguyên tắc cơ bản. Cái này từ khóa có lẽ nên là số một trong danh sách học tập của bạn.
Đây thực sự là gì?
Nói một cách đơn giản, cái này là một con trỏ, một cách để tham chiếu đến đối tượng nào được gọi là hàm hoặc phương thức trong mã JavaScript. Theo thuật ngữ của giáo dân, điều này là phần bên trái của dấu chấm.
Điều này có hai cách sử dụng chính. Hãy khám phá chúng với một số ví dụ.
Tạo đối tượng bằng this
function Book(title, author, genre) { this.title = title; this.author = author; this.genre = genre; } const book1 = new Book("Lord Of The Rings", "J.R.R. Tolkien", "Fantasy"); const book2 = new Book("Tools Of Titans", "Tim Ferriss", "Self-help"); console.log(book1); console.log(book2);
Đoạn mã trên tạo ra kết quả sau:
Ở đây, chúng tôi đã xác định một hàm khởi tạo mà từ đó chúng tôi tạo các đối tượng sách lấy tiêu đề, tác giả và thể loại làm tham số.
Hàm khởi tạo là một hàm “bản thiết kế” đối tượng mà từ đó chúng ta có thể tạo các đối tượng có tên đã cho (trong trường hợp của chúng ta là Book).
81% người tham gia cho biết họ cảm thấy tự tin hơn về triển vọng công việc công nghệ của mình sau khi tham gia một cuộc thi đào tạo. Kết hợp với bootcamp ngay hôm nay.
Sinh viên tốt nghiệp bootcamp trung bình đã dành ít hơn sáu tháng để chuyển đổi nghề nghiệp, từ khi bắt đầu bootcamp đến khi tìm được công việc đầu tiên của họ.
Chúng tôi đã tạo một đối tượng có tên là myBook và truyền các tham số bắt buộc (được gọi là đối số khi chúng tôi gọi hoặc gọi một hàm, trái ngược với các tham số khi chúng tôi định nghĩa nó).
Cuối cùng, chúng tôi đăng nhập myBook và nhận lại đối tượng với các thuộc tính tương ứng của nó. Bằng cách này, mỗi đối tượng sách mới mà chúng tôi tạo sẽ được gán các giá trị đã chuyển cho nó.
Truy cập các thuộc tính bằng this :
const girl = { name: "Sarah", age: 26, introduce() { console.log( "Hi! " + "I'm " + this.name + " and I'm " + this.age + " years old." ); }, };
Ở đây chúng ta đã định nghĩa một biến có tên là girl chứa một đối tượng có các thuộc tính tên và tuổi, và một hàm giới thiệu.
Hàm ghi lại một câu giới thiệu bằng cách sử dụng các thuộc tính của đối tượng, truy cập chúng bằng this .w being_property.
Cái này và phạm vi trong JavaScript
Theo mặc định, khi được sử dụng trong phạm vi toàn cục, nghĩa là không nằm trong một hàm hoặc đối tượng đã xác định, this sẽ tham chiếu đến đối tượng toàn cục. Trong trình duyệt, cửa sổ là đối tượng chung.
Khi bạn khai báo một số dữ liệu nguyên thủy (chuỗi, số, boolean…), một đối tượng hoặc một hàm trong JavaScript, tất cả chúng đều được gắn vào đối tượng global (window).
Bất cứ thứ gì bạn viết "ngoài trời", bạn có thể đọc như thể có một cửa sổ. được viết trước nó. Hãy xem đoạn mã này:
function returnThis() { return this; }
Đầu tiên, chúng tôi xác định một hàm được gọi là returnThis trong phạm vi toàn cầu trả về giá trị của this . Sau đó, chúng tôi gọi nó bằng cách viết returnThis()
.
Vì nó có phạm vi toàn cầu, chúng tôi có thể coi nó là window.returnThis()
, trả về cho chúng ta những gì ở bên trái của dấu chấm.
Các hàm đối tượng a.k.a. các phương thức
Nếu bây giờ chúng ta xác định một đối tượng mới có cùng chức năng bên trong nó (được gọi là phương thức đối tượng) và chúng ta gọi nó một lần nữa, chúng ta sẽ nhận được đối tượng đó (được biểu thị bằng dấu ngoặc nhọn) trả về cho chúng ta.
const object = { returnThis() { return this; }, }; object.returnThis();
Ý tưởng của điều này và đó là ba giải pháp
Nếu một hàm không được liên kết trực tiếp với một đối tượng, thì this bên trong của hàm sẽ tham chiếu đến đối tượng toàn cục.
const weirdBehaviorObject = { directlyTiedFunction() { return this; }, directlyTiedOuterFunction() { return function indirectNestedFunction() { return this; }; }, };
Hãy chạy điều này trong trình duyệt và xem những gì chúng ta nhận được:
Chúng tôi đã xác định một đối tượng có một hàm trả về this một lần nữa và một hàm khác trả về một hàm bên trong, sau đó trả về this .
Khi chúng ta muốn gọi hàm gián tiếp, trước tiên chúng ta viết ()
một lần để gọi hàm bên ngoài trả về hàm bên trong.
Sau đó, chúng tôi gọi bên trong bằng một ()
khác trả về cửa sổ.
Đây là một trong những hành vi bí ẩn của JavaScript và nó dẫn đến một số bất ngờ không mong muốn và không mong muốn.
May mắn thay, có nhiều cách để giải quyết vấn đề này. Cách đầu tiên là đóng cửa, đó là cách nó được thực hiện trước ES6. Cách thứ hai là sử dụng các hàm mũi tên và cách thứ ba là sử dụng phương thức liên kết, có liên quan chặt chẽ đến phương thức gọi và áp dụng.
# 1 Giải quyết điều này có đóng cửa
Bao đóng là một kho lưu trữ bộ nhớ liên tục, có nghĩa là biến không biến mất khi hàm kết thúc thực thi. Nó được tạo bởi công cụ JavaScript khi một hàm lồng nhau đang tham chiếu đến một biến được xác định trong một hàm bên ngoài để nó có quyền truy cập vào nó ngay cả khi hàm bên ngoài chạy xong. Đây là giao diện với cái này của chúng tôi ví dụ:
const objectWithClosure = { closureFunction() { const self = this; return function enclosedFunction() { return self; }; }, };
Chúng tôi đã xác định một đối tượng với hàm Close giá trị. Vì hàm Close được liên kết trực tiếp với đối tượng chứa nên giá trị của this đề cập đến nó. Bây giờ, trong Chức năng kèm theo của chúng tôi, this thường sẽ tham chiếu đến đối tượng cửa sổ. Vì chúng tôi đã sử dụng tính năng đóng để truy cập this từ hàm chứa, chúng tôi có thể bảo toàn đối tượng đang gọi như giá trị của nó.
# 2 Giải quyết điều này với các chức năng mũi tên
Giải pháp thứ hai được cho là sử dụng một trong những tính năng tốt nhất đi kèm với ES6, đó là các hàm mũi tên.
Các hàm mũi tên thể hiện một cú pháp ngắn gọn hơn để viết các hàm. Ngoài ra, họ sẽ tìm kiếm một cấp độ trong phạm vi để tìm kiếm điều này, ý nghĩa trong chức năng mà nó chứa trong đó.
Vì vậy, nếu chúng ta xác định đối tượng của mình như vậy:
const arrowFunctionObject = { outerFunc() { return () => this; }, };
Chúng ta có thể thấy rằng hàm mũi tên trả về đối tượng thực chứ không phải cửa sổ.
Đó là bởi vì nó đã tìm kiếm bên ngoài Function đã gọi nó, nơi cái này đề cập đến arrowFunctionObject. Vì vậy, các hàm mũi tên có một loại bao đóng tích hợp sẵn.
Các hàm mũi tên lồng nhau
Tất nhiên, đây là JavaScript, vì vậy đây là một gotcha khác. Đó là điều có thể bạn sẽ không bao giờ gặp phải ngoài một cuộc phỏng vấn kỹ thuật, nhưng đó là lý do đủ để biết điều đó.
Điều gì xảy ra nếu chúng ta lồng một hàm mũi tên vào bên trong một hàm thông thường và lại vào bên trong một hàm khác? Nó trông như thế này:
const arrowNestedInRegularFunctionObject = { outerFunction() { return function regularFunction() { return () => this; }; }, };
Đối tượng của chúng ta có một hàm bên ngoài, khi được gọi, sẽ trả về hàm bên trong, hàm thông thường.
Sau đó, chúng tôi gọi hàm thường và nó trả về hàm mũi tên trong cùng.
Bây giờ, khi gọi nó, nó sẽ trả về đối tượng cửa sổ.
Hàm mũi tên sẽ tìm kiếm chỉ 1 cấp độ tăng trong phạm vi. Vì hàm thường xuyên chứa nó không được liên kết trực tiếp với đối tượng của chúng ta, nên cửa sổ được trả về thay thế.
Tuy nhiên, nếu chúng ta lồng một hàm mũi tên vào bên trong một hàm mũi tên, bên trong một hàm thông thường, chúng ta sẽ nhận được kết quả mong đợi, đó là đối tượng chứa thực tế.
const nestedArrowFunctionObject = { outerFunction() { return () => { return () => this; }; }, };
Trong trường hợp này, hàm mũi tên bên trong nhìn lên hàm bên ngoài. Bên ngoài cũng là chức năng mũi tên nên nó sẽ tra thêm một bậc nữa. Chức năng bên ngoài thông thường được liên kết trực tiếp với lệnh gọi
và kết quả là đối tượng là thứ được trả về là this .
# 3 Giải quyết điều này với phương thức ràng buộc
Cuối cùng, giải pháp thứ ba là sử dụng phương thức ràng buộc. Phương thức liên kết được sử dụng để khai báo rõ ràng cái gì this nên tham khảo. Nó nhận đối tượng được truyền dưới dạng đối số và liên kết nó với hàm của this từ khóa.
const arrowNestedInRegularFunctionObject = { outerFunction() { return function regularFunction() { return () => this; }.bind(arrowNestedInRegularFunctionObject); }, };
Trong ví dụ này, chúng tôi đã xâu chuỗi ràng buộc với hàm thường trả về đối tượng cửa sổ là this . Chúng tôi chuyển nó đối tượng mà chúng tôi muốn được tham chiếu là this như một đối số và vấn đề của chúng ta đã được giải quyết.
Cái này không khó khi bạn hiểu JavaScript
Phù! Đó là một sự lặn. Bây giờ, bạn có thể hỏi, tại sao tất cả những rắc rối và nhầm lẫn với this ?
Lý do là, không giống như mọi thứ khác trong JavaScript, this là phạm vi động. Điều đó có nghĩa là công cụ JavaScript xác định cái gì cái này đại diện cho thời gian chạy khi mã được thực thi, bằng cách xem từ đâu đến và ai đang gọi nó.
Ngược lại, mọi thứ khác trong JavaScript đều có phạm vi từ vựng, có nghĩa là giá trị của nó được xác định khi biến được xác định, khi mã được viết.
Cảm ơn vì điều này , chúng ta có thể tạo một đối tượng “bản thiết kế” một lần và tạo động các đối tượng với các giá trị thuộc tính khác nhau như chúng ta đã thấy trong ví dụ sách của mình.
Chúng tôi cũng có thể tạo các phương thức hiển thị và thao tác các thuộc tính của đối tượng với this .wallow_property.
Chúng tôi có thể giải quyết các vấn đề khó hiểu của JavaScript và tự tin chỉ huy hành vi của JavaScript, đồng thời tạo ra kết quả như mong đợi.
Bây giờ bạn đã hiểu điều này trong JavaScript, cũng như một số khái niệm cơ bản khác, bạn có thể thử nghiệm, thực hành và tự tin hơn để thực hiện các bước để thành thạo JavaScript.
Bạn đã nhận được cái này !