1. 和C++/C#/Java类似,函数在被调用的时候用this指向函数的上下文对象。
1.1. 当函数没有与某个上下文对象绑定的时候,this指向全局的window对象。例如:
window.number = 10;
function printNumber() {
console.log(this.number);
}
printNumber();
在上述代码中,由于this指向windows对象,因此输出为10。
1.2.当函数与某个对象绑定的时候,this指向该对象。例如:
function printNumber() {
console.log(this.number);
}
var obj = {
number: 8,
print: printNumber
};
obj.print();
在上述代码中,函数printNumber通过对象obj调用,因此this指向了对象obj。代码的输出是8。
2. 函数还可以通过apply和call两种方式传入this指向的对象并调用。
2.1 通过apply调用函数时,第一个参数指定this指向的对象,第二个参数是一个参数数组,或者一个arguments对象。例如:
function addNumber(num1, num2) {
console.log(this.number + num1 + num2);
}
var obj = {
number: 8
};
function applyAdd1(num1, num2) {
addNumber.apply(obj, [num1, num2]);
}
function applyAdd2(num1, num2) {
addNumber.apply(obj, arguments);
}
applyAdd1(4, 5);
applyAdd2(4, 5);
在上述代码中,applyAdd1和applyAdd2都是通过apply调用函数addNumber,只是传入第二个参数的方法不一样。它们的功能也是一样的,都输出17。
2.2 如果用call调用函数,第一个参数传入this指向的对象,后面顺序传入其他参数。例如:
function addNumber(num1, num2) {
console.log(this.number + num1 + num2);
}
var obj = {
number: 8
};
function callAdd(num1, num2) {
addNumber.call(obj, num1, num2);
}
callAdd(4, 5);
和前面一样,上述代码仍然输出17。
3. 我们还可以用bind函数显示地把函数和一个对象绑定起来,然后再在这个对象上调用该函数。例如:
function addNumber(num1, num2) {
console.log(this.number + num1 + num2);
}
var obj = {
number: 8
};
var addObjNumber = addNumber.bind(obj);
addObjNumber(4, 5);
由于函数addNumber通过bind函数显示地和对象obj绑定起来,再调用addNumber的时候,this指向的就指向了obj。因此,上述代码仍然输出17。
4. 可以在函数声明之后立即调用。利用这个特性,我们可以实现Singleton模式。下面是一段示例代码:
var singleton = function(data) {
function Singleton() {
this.data = data;
};
Singleton.prototype.func = function() {
console.log(this.data);
}
return new Singleton(data);
}("Hello, singleton");
singleton.func(); // Hello, singleton