01/10/2018, 10:59
Ai rành JavaScript giúp mình xem tại sao lại kết quả lại như vậy!
var obj = {a: 'Custom'};
// This property is set on the global object
var a = 'Global';
function whatsThis(arg) {
return this.a; // The value of this is dependent on how the function is called
}
whatsThis(); // Returns 'Global'
whatsThis.call(obj); // Returns 'Custom'
whatsThis.apply(obj); // Returns 'Custom'
Nguồn: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
mình chạy lệnh này từng dòng một trên ‘Console của browser’ và Terminal nó ra kết quả giống như comment ở trên.
Những khi đánh cả một đoạn giống y hết hoặc copy sang y nguyên rùi dùng ‘node’ chạy thì… Kết quả lại khác ? Tại sao vậy? Ai rành giúp mình với…
Bài liên quan
Mình không rành JavaScript, nên mình thấy đoạn này sai sai:
Ở trên thì là định nghĩa hàm
whatsThis
có tham số. Ở dưới lại gọi hàmwhatsThis
không có tham số. Như vậy nếu theo các ngôn ngữ mình đã biết thì hàmwhatsThis
không có tham số là chưa được định nghĩa → Kết quả nhận được sẽ là undefinedTrong 1 file JS, chính xác hơn là trong 1 module, tất cả câu lệnh khai báo (khai báo biến, khai báo hàm) được bao bởi 1 object và gán nó vào 1 biến ngầm this. Với đoạn JS của bạn, object ngầm như thế này:
Ba lời gọi hàm (function call) trở thành:
Việc xác định từ khoá this phụ thuộc vào vị trí lời gọi hàm.
Trong trường hợp 1, this ngầm toàn cục truyền vào hàm whatsThis, this.a có giá trị là ‘Global’
Trường hợp 2 và 3, do gọi thêm method call() và method apply() (function trong JS là object, vì vậy function có method, bạn chú ý sau whatsThis không có cặp () ), sẽ thay đổi this ngầm thành giá trị được truyền vào call(), apply(). Lúc này, this được thay thành obj. Trong hàm whatsThis, this.a là obj.a, kết quả trả về là ‘Custom’
Đúng rùi anh. Nhưng sao trên Terminal nó lại ra kết quả khác với thực tế nhỉ @@! cái này mới khiến em thắc mắc anh ạ.
Vậy chắc mình nhầm bên Front-end. Mỗi file sẽ được gán ngầm định 1 biến global, là biến window, nên 2 lệnh này như nhau:
Còn bên Node chắc không có vụ gán ngầm this, khai báo sau thì biến this luôn là object rỗng { }. Đoán vậy thôi.
Cảm ơn anh đã nhiệt tình giúp đỡ newbie trong như em g9! cái này chắc em học thêm vài tháng or vài năm mới biết mất! dù sao cũng cảm ơn anh nhé
Môi trường node và môi trường browser là khác nhau.
Khi học về this hay “strict” mode thì thường họ sẽ nói về sự khác nhau này.
Hi,
Ở trong javascript, nếu bạn chạy trên môi trường nodejs thì global object là global còn trên trình duyệt là object window.
Khi bạn khai báo
var a = 'Global'
thì a sẽ ở module wrapper.Nên khi bạn gọi hàm
whatsThis()
ở global thì tức là bạn đang chạywhatsThis.call(this)
,this
ở đây lại là một object không cùng context với module wrapper function.vì vậya
vàthis.a
trong functionwhatsThis
không cùng 1 context nênthis.a
sẽ returnundefined
. ( Mình đoán vậy )Nhưng nếu bạn chạy trên google dev tool trên trình duyệt. Lúc này biến khai báo và từ khóa
this
nằm cùng 1 context nên kết quả sẽ trả về đúnga === 'Global'
Bạn có thể log trên console của window để xem các biến Javascript engine xử lý như thế nào.
Quay trở lại console của linux. Bắt đầu thử xem các biến được nodejs sắp xếp như thế nào
Khi nhấn
enter
và bạn tìm xuống cuối object được log ra màn hình. Bạn vấn thấy kết quả ra đúngGlobal
và các biến được khai báo nằm trong context này.Nhưng khi bạn viết trong file. và chạy bằng lệnh
node tenfile.js
Kết quả sẽ ra như thế này:Là do ở browser thì scope to nhất là
global
. Nhưng trong nodejs, khi bạn sử dụng file hay module thì các biến, hàm khai báo chỉ nằm trong module đó. sử dụng context của module đó. Các biến này thì private trong module.Cơ chế của nodejs khá phức tạp. bạn có thể đọc document của nodejs để tìm hiểu thêm. Nếu bạn muốn đưa các biến khai báo ra scope to nhất. bạn có thể sử dụng luôn biến đó mà không cần khai báo bằng từ khóa
var
Khi đó kết quả sẽ là :
Còn khi bạn chạy hàm
whatsThis()
nhưng được call bởi 1 Object khác. Thì biến this trong function sẽ trỏ đến object này.Nói chung là biến
this
trong javascript khá phức tạp. Bạn nên làm quen dần. =))) Đúng là phải mất mấy năm mới hiểu được phần nào của JS.welcome to Js world! =)))
Bạn làm mình nhớ tới là Node sử dụng CommonJS để phân chia module. Học lâu chưa xem lại.
Hay quá cảm ơn anh @hibariwl