this指针的用法
常规用法
对this的理解是,指向 直接操作这个量的函数(或变量、对象)所属的对象 的指针,也就是指向爹的爹,指向爷爷。通过几个例子了解一下this的常见用法:
var name = 1;
var util = {
name: 2,
myName: this.name
getName: function(){
return this.name;
},
sub: {
name: 3,
getName: function(){
console.log(this);
return this.name
}
}
}
常规的this使用及结果
console.log(util.myName); //1 this指向window
console.log(util.getName()); // 2 this指向util
console.log(util.sub.getName()); // 3 this指向sub
如果是下列情况
var a = util.getName;
console.log(a()); //结果为1
解释:a=util.getName;
使得 a 成为一个全局函数,即
a=function(){return this.name;}
此时的this指向 window ,得到 window.name
另一种情况:
var b = util.sub;
console.log(b.getName()); // 3
解释:同理上个例子, b 是一个全局对象,
b = {
name: 3,
getName: function(){
console.log(this);
return this.name
}
b.getName()
中的this即指向getName()所属的对象 b ,得到 b.name
还有,如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。例子如下:
function getName(){
this.name = 1;
return {}; // 返回对象
}
var a = new getName;
console.log(a.name); //undefined
function getName(){
this.name = 1;
return 2; // 返回非对象
}
var d = new getName;
console.log(d.name); //1
匿名函数中的this
在非严格模式下,匿名函数的执行环境具有全局性,因此其this对象指向window.
例子如下:
var obj = {
birth: 1990,
getAge: function () {
var b = this.birth; // 1990
var fn = function () {
return new Date().getFullYear() - this.birth; // this指向window(非严格模式)或undefined(严格模式)
};
return fn();
}
};
要想获得预期的结果,可以使用以下hack写法,加一行 var that = this;
var obj = {
birth: 1990,
getAge: function () {
var b = this.birth; // 1990
var fn = function () {
var that = this;
return new Date().getFullYear() - that.birth; // that指向obj
};
return fn();
}
};
箭头函数中的this
箭头函数和匿名函数的区别:箭头函数内部的this是词法作用域,由上下文确定。
回顾前面的例子,由于JavaScript函数对this绑定的错误处理,无法得到预期的结果。
现在,箭头函数完全修复了this的指向,this总是指向词法作用域,也就是外层调用者obj:
var obj = {
birth: 1990,
getAge: function () {
var b = this.birth; // 1990
var fn = () => new Date().getFullYear() - this.birth; // this指向obj对象
return fn();
}
};
obj.getAge(); // 25
如果使用箭头函数,以前的那种hack写法:
var that = this;
就不再需要了。
由于this在箭头函数中已经按照词法作用域绑定了,所以,用call()或者apply()调用箭头函数时,无法对this进行绑定,即传入的第一个参数被忽略:
var obj = {
birth: 1990,
getAge: function (year) {
var b = this.birth; // 1990
var fn = (y) => y - this.birth; // this.birth仍是1990
return fn.call({birth:2000}, year);
}
};
obj.getAge(2015); // 25