在Javascript中this总是指向调用它所在方法的对象。因为this是在函数运行时,自动生成的一个内部对象,只能在函数内部使用。
1.全局的函数调用
function showFullName() {
this.firstName = "Lily"
this.lastName = "Jams"
console.log(this.firstName + " " + this.lastName);
}
showFullName(); // Lily Jams
showFullName()是全局性的方法,属于全局性调用,因此this就代表全局对象window。
2.对象函数调用
var person = {
firstName: "Lily",
lastName: "Jams",
showFullName: function () {
console.log(this.firstName + " " + this.lastName);
}
}
person.showFullName(); // Lily Jams
showFullName函数作为person对象的方法调用,this指向的是这个上级对象,即调用方法的对象person。
3.构造函数的调用
function Person() {
this.firstName = "Lily"
this.lastName = "Jams"
}
var person = new Person();
console.log(person.firstName + " " + person.lastName); // Lily Jams
构造函数中的this指向新创建的对象本身。
4.当使用this的方法被用作回调函数时
var person = {
firstName: "Lily",
lastName: "Jams",
showFullName: function () {
console.log(this.firstName + " " + this.lastName);
}
}
function printName(object) {
object();
}
printName(person.showFullName); // undefined undefined
printName方法属于全局window对象,当将person.showFullName方法作为其方法的回调函数传入,person.showFullName方法里的this将不再指代person对象,而是指向window对象,所有firstName、lastName为undefined。
结论:当上下文环境改变时,this关键词不再指代原对象,而是指代调用该方法的对象。
那么当使用this的方法被用作回调函数时,获取正确值的方式,使用call()、apply()、bind()方法给this设置特定的值
printName(person.showFullName.bind(person)); // Lily Jams
5.当this被用于闭包函数时
var person = {
name: "Lily Jams",
parents: [{type: "Father", name:"Steven Jams"}, {type: "Mother", name:"Susan Jams"}],
showParent: function () {
this.parents.forEach(function (item) {
console.log(this.name + " " + item.type + " name is " + item.name);
});
}
}
person.showParent(); // undefined Father name is Steven Jams
// undefined Mother name is Susan Jams
闭包使用this关键词无法访问外部函数的this变量。要获取到正确的值,需在闭包函数外部将this赋值给其他变量
var person = {
name: "Lily Jams",
parents: [{type: "Father", name:"Steven Jams"}, {type: "Mother", name:"Susan Jams"}],
showParent: function () {
var that = this;
this.parents.forEach(function (item) {
console.log(that .name + " " + item.type + " name is " + item.name);
});
}
}
person.showParent(); // Lily Jams Father name is Steven Jams
// Lily Jams Mother name is Susan Jams
6. 当this被用于使用apply()、call()方法调用时
apply和call都是为了改变函数体内部的this指向。 其具体的定义如下:
call方法:
语法:call(thisObj,Object)
定义:调用一个对象的一个方法,以另一个对象替换当前对象。
说明:
call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。
apply方法:
语法:apply(thisObj,[argArray])
定义:应用某一对象的一个方法,用另一个对象替换当前对象。
说明:
如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。
如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。
var personAction = {
showParent: function (params) {
console.log("Person name is " + this.name)
this.parents.forEach(function (item) {
console.log(item.type + " name is " + item.name);
});
console.log("params " + params)
}
}
var person = {
name: "Lily Jams",
parents: [{type: "Father", name:"Steven Jams"}, {type: "Mother", name:"Susan Jams"}],
}
personAction.showParent.call(person, "hahahahahah.....");
// Person name is Lily Jams
// Father name is Steven Jams
// Mother name is Susan Jams
// params hahahahahah.....