2011-12-29 36 views
18

Ai có thể giải thích cho tôi tại sao A là đúng và B là sai? Tôi đã mong đợi B cũng đúng.Giá trị này trong hàm ẩn danh JavaScript

function MyObject() { 

}; 

MyObject.prototype.test = function() { 
    console.log("A", this instanceof MyObject); 
    (function() { 
     console.log("B", this instanceof MyObject); 
    }()); 
} 

new MyObject().test(); 
+5

Chào mừng bạn đến với phạm vi chức năng trong JavaScript. – zzzzBov

+1

@zzzzBov: Đó không phải là đóng cửa. – SLaks

+0

Bạn có thể muốn sử dụng một cặp parens bổ sung để cải thiện khả năng đọc: '(new MyObject()) .test()' –

Trả lời

15

this là đặc biệt.Nó đề cập đến đối tượng mà hàm đang được gọi thay mặt (thường là thông qua cú pháp dấu chấm).

Vì vậy, trong trường hợp A, chức năng này đang được gọi thay mặt cho đối tượng MyObject mới. B là một chức năng khác không được gọi rõ ràng thay mặt cho bất kỳ đối tượng nào, do đó, this mặc định là đối tượng chung (window).

Nói cách khác, this thay đổi tùy thuộc vào cách chức năng là được gọi là, không phải vị trí hoặc cách xác định. Thực tế là bạn đang sử dụng một hàm ẩn danh (được định nghĩa bên trong một hàm khác) là trùng hợp ngẫu nhiên và không ảnh hưởng đến giá trị của this.

+4

Câu lệnh của bạn" 'this' thay đổi tùy theo chức năng * được gọi là *, không ở đâu hoặc cách nó được định nghĩa ", có thể gây hiểu nhầm.Trong thực tế, 'this' chỉ đơn giản là chủ sở hữu của hàm được gọi - và đó là chính nó luôn luôn được xác định rõ ràng hoặc mặc định cho đối tượng toàn cầu. 'myVar.doSomething = doSomething;' định nghĩa hàm 'myVar.doSomething' là' doSomething' trong đó 'this' sẽ luôn luôn trỏ đến' myVar' khi gọi 'myVar.doSomething()', bất kể ở đâu 'myVar.doSomething() 'được gọi từ. Tuyên bố của bạn có thể đề xuất khác. – Navigateur

3

this được đặt dựa trên cách bạn gọi hàm.
Chức năng ẩn danh của bạn là một cuộc gọi hàm bình thường, vì vậy this là đối tượng chung.

Bạn có thể viết (function() { ... }).call(this) để gọi rõ ràng với số this của mình.

+0

Vâng, tôi giả sử chế độ nghiêm ngặt, vậy ... ':)' –

+0

@ ŠimeVidas: Cái gì? – SLaks

+0

... do đó 'this' is' undefined'. –

26

Bên trong hàm ẩn danh this là đối tượng chung.

Bên trong của test, đây là trường hợp của MyObject mà trên đó phương thức được gọi.


Bất cứ khi nào bạn gọi một chức năng như thế này:

somceFunction(); // called function invocation 

thisluôn đối tượng toàn cầu, hoặc undefined trong chế độ nghiêm ngặt (trừ khi someFunction đã được tạo ra với bind** - xem dưới đây)

Bất cứ khi nào bạn gọi một chức năng như thế này

foo.someMethod(); //called method invocation 

this được thiết lập để foo


** ECMAScript5 định nghĩa một hàm bind cho phép bạn tạo một hàm mà có một thiết lập trước giá trị cho this

Vì vậy

này
var obj = { a: 12 }; 
    var someFunction = (function() { alert(this.a); }).bind(obj); 
    someFunction(); 

Nguyên nhân someFucntion được gọi với this bằng obj, và cảnh báo 12. Tôi mang cái này lên chỉ cần lưu ý rằng đây là một ngoại lệ tiềm năng để các quy tắc tôi đã đề cập về chức năng gọi là

someFunction(); 

luôn có this bằng đối tượng chung (hoặc undefined ở chế độ nghiêm ngặt)

+0

Dòng '(function() {alert (this.a);}). Bind (obj)' là chính xác những gì tôi đang tìm kiếm - ràng buộc ngữ cảnh với một hàm ẩn danh. Hoạt động hoàn hảo, +1 –

+0

bạn cũng có thể đặt 'this' bằng cách sử dụng' func.call (this, arg1, arg2 ..) ' – Omu

6

Trong chức năng ẩn danh, this được gắn với đối tượng chung (window trong môi trường trình duyệt).

Có rất nhiều cách tiếp cận các ví dụ:

var self = this; 
(function() { 
    console.log("B", self instanceof MyObject); 
}()); 

hoặc

(function() { 
    console.log("B", this instanceof MyObject); 
}).call(this); 
Các vấn đề liên quan