2013-10-09 27 views
6

Tôi đang học javascript và tôi đã gặp một nghi ngờ. Tại sao giá trị của "this" không được xác định trong ví dụ đầu tiên, nhưng in ra một cách chính xác trong lần thứ hai.Tại sao giá trị "này" thay đổi.?

dụ 1:

var myNamespace = { 
    myObject: { 
     sayHello: function() { 
      console.log("name is " + this.myName); 
     }, 
     myName: "john" 
    } 
}; 

var hello = myNamespace.myObject.sayHello; 

hello(); // "name is undefined" 

dụ 2:

var myNamespace = { 
    myObject: { 
     sayHello: function() { 
      console.log("Hi! My name is " + this.myName); 
     }, 
     myName: "Rebecca" 
    } 
}; 

var obj = myNamespace.myObject; 

obj.sayHello();//"Hi! My name is Rebecca" 

Tại sao giá trị của "này" thay đổi trong chức năng. Tôi đang thiếu khái niệm gì?

+4

Đó là cách 'this' hoạt động. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this – SLaks

+2

Kỳ vọng của bạn là tốt, ngữ nghĩa 'this' của JavaScript bị hỏng. :-) – Waldheinz

+0

nó là javascript không phải là "java script" .. rất rất tuyệt vời khác biệt .. :) –

Trả lời

3

trường hợp Trước tiên, bạn chỉ nhận được các tài liệu tham khảo của hàm đến vairable hello, và gọi nó từ bối cảnh toàn cầu (cửa sổ trong các trình duyệt, toàn cục trong nút), Vì vậy, this trở thành những gì được gọi hàm này ngoại trừ (các hàm bị ràng buộc). Bạn luôn có thể thiết lập các bối cảnh một cách rõ ràng bằng function.call hoặc thiết lập bối cảnh rõ ràng để các chức năng sử dụng Ecma5 function.bind

hello.call(myNamespace.myObject); //now you are setting the context explicitly during the function call. 

hoặc chỉ ràng buộc nó trong khi nhận được các tài liệu tham khảo chức năng.

var hello = myNamespace.myObject.sayHello.bind(myNamespace.myObject); //Now no matter where you call it from `this` will point to the context of myObject 

Trường hợp thứ hai bạn gọi nó từ chính đối tượng đó this trỏ đến đối tượng.

1

Trong trường hợp đầu tiên, đối tượng ngụ ý this là phạm vi toàn cầu. Bởi vì không có myName trong phạm vi toàn cầu, bạn sẽ không được xác định.

Nếu bạn muốn có một chức năng miễn phí với các hợp this, sử dụng bind:

var hello = myNamespace.myObject.sayHello.bind(myNamespace.myObject); 
Các vấn đề liên quan