Understand JavaScript - Objects , Functions And This
Chúng ta đã nói khá nhiều về Function thực sự là gì ? Nó đơn giản chỉ là một Object có một vài đặc trưng so với Object thông thường mà thôi , trong bài viết này mình sẽ đi sâu hơn giải thích về hoạt động của hàm , khi nó được gọi , khi nó được thực thi. Hãy nhớ về EC chúng ta đã nói ở những bài viết trước.
- Bất kì hàm nào được gọi thì một Execution Context mới được tạo ra đừng nhầm lẫn điều này với Object mà mình đã nói ở bài trước , Object (function) đặt vào trong bộ nhớ là một function có các Property nó có thuộc tính Name , thuộc tính code nơi chứa tất cả code trong hàm.
- Nhưng khi code trong Property code được gọi và thực thi thì EC mới được tạo ra và được vào Execution Context Stack để thực thi , bạn hãy nghĩ rằng EC như nó chỉ tập trung vào property Code của hàm mà thôi đơn giản hơn thì EC chỉ quan tâm điều gì xảy ra khi tôi chạy code trong Property Code của object (function) đó.
- Mỗi EC sẽ tạo ra một
+ Variable Environment , nơi chứa các biến được tạo ra trong function .
+ Outer Environment : Nó tham chiếu đến môi trường bên ngoài của EC , môi trường chứa EC đó , nó cho biết Scope Chain của EC đó là gì ? nói cách khác khi mình yêu cầu một biến trong function đó mà nó không có trong Variable Environment của EC đó thì nó sẽ đi ra môi trường bên ngoài tìm trong Scope Chain .
+ biến This : JSE sẽ quyết định biến this được trỏ vào object nào.
Một vài ví dụ để bạn hiểu hơn về biết this.
- Kết quả :
- Biến this sẽ trỏ đến Object gọi hàm chứa nó trong trường hợp này nó chỉ vào Global Object vì chúng ta đang chạy trên Browser nên Global Object chính là Window.
Bạn có thể thấy rằng hàm a được gán vào như một Property của Window (window nó lấy tất cả các biến , hàm và object có scope là Global , lưu trong nó như những Property ) , khi bạn gọi hàm a chính là bạn dùng Window để gọi hàm a lên .. để chứng minh điều này mình sẽ viết code tường mình hơn.
Kết quả vẫn tương tự.
- Bạn có thể thấy hình mình khoanh đỏ hàm a được đặt bên trong Window như một Property của nó.
Ví dụ 2 :
Kết quả :
Bạn có thể thấy rằng ở dòng 5 thì EC xác định biến This trỏ đến Object C nhưng ở trong hàm setname bạn có thể thấy biến this lại trỏ đến Window như vậy mình có thể rút ra một kết luận.
- Nếu EC không tìm được thằng gọi nó thì EC sẽ mặc định xác nhận biến this trỏ đến Global Object.
từ đó bạn có thể thấy hàm setname không thể thiết lập lại name cho Object C được vì this lúc này không trỏ về c nữa , bây giờ bạn có thể thấy trong Window có Property name (((:
- Một lưu ý mình muốn nói rằng , mỗi khi bạn gọi một hàm để thực thi thì EC sẽ xác định biến this sẽ trỏ đến Object nào , một hàm nhưng trong các hoàn cảnh thực thi khác nhau biến this của nó sẽ trỏ đến các Object khác nhau.
- Như vậy để biến this tường minh , bạn muốn biến this trỏ đến Object mà bạn muốn , mình sẽ trình bày một cách rất phổ biến , tạo ra một biến cùng trỏ đến Object.
Bạn có thể thấy rằng mình đã tạo ra một biết self cùng trỏ đến Object C (vì c là object nên self và c sẽ liên kết theo kiểu tham chiếu , 2 biến sẽ cùng trỏ đến một Object) và điều này dẫn đến nếu bạn thay đổi Self thì sẽ thay đổi cả C luôn.
- Khi chạy hàm setname , biến self không được khai báo trong hàm như vậy JSE sẽ nhìn vào trong Scope Chain và tìm kiếm self ở môi trường bên ngoài
- Bất kì hàm nào được gọi thì một Execution Context mới được tạo ra đừng nhầm lẫn điều này với Object mà mình đã nói ở bài trước , Object (function) đặt vào trong bộ nhớ là một function có các Property nó có thuộc tính Name , thuộc tính code nơi chứa tất cả code trong hàm.
- Nhưng khi code trong Property code được gọi và thực thi thì EC mới được tạo ra và được vào Execution Context Stack để thực thi , bạn hãy nghĩ rằng EC như nó chỉ tập trung vào property Code của hàm mà thôi đơn giản hơn thì EC chỉ quan tâm điều gì xảy ra khi tôi chạy code trong Property Code của object (function) đó.
- Mỗi EC sẽ tạo ra một
+ Variable Environment , nơi chứa các biến được tạo ra trong function .
+ Outer Environment : Nó tham chiếu đến môi trường bên ngoài của EC , môi trường chứa EC đó , nó cho biết Scope Chain của EC đó là gì ? nói cách khác khi mình yêu cầu một biến trong function đó mà nó không có trong Variable Environment của EC đó thì nó sẽ đi ra môi trường bên ngoài tìm trong Scope Chain .
+ biến This : JSE sẽ quyết định biến this được trỏ vào object nào.
Một vài ví dụ để bạn hiểu hơn về biết this.
- Kết quả :
- Biến this sẽ trỏ đến Object gọi hàm chứa nó trong trường hợp này nó chỉ vào Global Object vì chúng ta đang chạy trên Browser nên Global Object chính là Window.
Bạn có thể thấy rằng hàm a được gán vào như một Property của Window (window nó lấy tất cả các biến , hàm và object có scope là Global , lưu trong nó như những Property ) , khi bạn gọi hàm a chính là bạn dùng Window để gọi hàm a lên .. để chứng minh điều này mình sẽ viết code tường mình hơn.
Kết quả vẫn tương tự.
- Bạn có thể thấy hình mình khoanh đỏ hàm a được đặt bên trong Window như một Property của nó.
Ví dụ 2 :
Kết quả :
Bạn có thể thấy rằng ở dòng 5 thì EC xác định biến This trỏ đến Object C nhưng ở trong hàm setname bạn có thể thấy biến this lại trỏ đến Window như vậy mình có thể rút ra một kết luận.
- Nếu EC không tìm được thằng gọi nó thì EC sẽ mặc định xác nhận biến this trỏ đến Global Object.
từ đó bạn có thể thấy hàm setname không thể thiết lập lại name cho Object C được vì this lúc này không trỏ về c nữa , bây giờ bạn có thể thấy trong Window có Property name (((:
- Một lưu ý mình muốn nói rằng , mỗi khi bạn gọi một hàm để thực thi thì EC sẽ xác định biến this sẽ trỏ đến Object nào , một hàm nhưng trong các hoàn cảnh thực thi khác nhau biến this của nó sẽ trỏ đến các Object khác nhau.
- Như vậy để biến this tường minh , bạn muốn biến this trỏ đến Object mà bạn muốn , mình sẽ trình bày một cách rất phổ biến , tạo ra một biến cùng trỏ đến Object.
Bạn có thể thấy rằng mình đã tạo ra một biết self cùng trỏ đến Object C (vì c là object nên self và c sẽ liên kết theo kiểu tham chiếu , 2 biến sẽ cùng trỏ đến một Object) và điều này dẫn đến nếu bạn thay đổi Self thì sẽ thay đổi cả C luôn.
- Khi chạy hàm setname , biến self không được khai báo trong hàm như vậy JSE sẽ nhìn vào trong Scope Chain và tìm kiếm self ở môi trường bên ngoài
Nhận xét
Đăng nhận xét