在 JavaScript 中,如同在大部分面向對象編程語言中一樣,`this`?是一個特殊的關鍵字,它常在被某個對象調用的方法中指向對象本身。`this`?的值可通過一系列簡單的步驟來確定:
* 如果函數是通過?`Function.call()`?或者?`Function.apply()`?調用,`this`?的值將會被設置為傳遞給?`.call()`?或?`.apply()`?的第一個參數。如果傳遞給?`.call()`或?`.apply()`?的第一個參數是?`null`?或?`undefined`,`this`?會指向全局對象(在 Web 瀏覽器中是?`window`?對象)。
* 如果被調用的函數是由?`Function.bind()`?創建的,`this`?將會是該函數被創建時傳遞給?`.bind()`?的第一個參數。
* 如果函數是作為一個對象的方法被調用,`this`?將會指向那個對象。
* 否則,當函數作為一個不依附任何對象的獨立函數被調用,`this`?會指向全局對象。
~~~
// A function invoked using Function.call()
var myObject = {
sayHello: function() {
console.log( "Hi! My name is " + this.myName );
},
myName: "Rebecca"
};
var secondObject = {
myName: "Colin"
};
myObject.sayHello(); // "Hi! My name is Rebecca"
myObject.sayHello.call( secondObject ); // "Hi! My name is Colin"
~~~
~~~
// A function created using Function.bind()
var myName = "the global object";
var sayHello = function() {
console.log( "Hi! My name is " + this.myName );
};
var myObject = {
myName: "Rebecca"
};
var myObjectHello = sayHello.bind( myObject );
sayHello(); // "Hi! My name is the global object"
myObjectHello(); // "Hi! My name is Rebecca"
~~~
~~~
// A function being attached to an object at runtime.
var myName = "the global object";
var sayHello = function() {
console.log( "Hi! My name is " + this.myName );
};
var myObject = {
myName: "Rebecca"
};
var secondObject = {
myName: "Colin"
};
myObject.sayHello = sayHello;
secondObject.sayHello = sayHello;
sayHello(); // "Hi! My name is the global object"
myObject.sayHello(); // "Hi! My name is Rebecca"
secondObject.sayHello(); // "Hi! My name is Colin"
~~~
當深度調用一個長命名空間的函數時,它通常會誘使你使用一個單一簡短的變量來引用實際的函數,以減少你所需要鍵入的代碼。重點是實例方法不能這么做,因為這會導致函數內的?`this`?值發生改變,從而導致不正確的結果。例如:
~~~
var myNamespace = {
myObject: {
sayHello: function() {
console.log( "Hi! My name is " + this.myName );
},
myName: "Rebecca"
}
};
var hello = myNamespace.myObject.sayHello;
hello(); // "Hi! My name is undefined"
~~~
但是,你可以安全的減少所有代碼,直到方法被調用的那個對象:
~~~
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"
~~~