首先写这篇博客是为了整理我自己有关于this关键字的一些基本理解,让自己的关于this理解更深刻些,后面会把它整理的更加完善。
javascript中this一直困扰着我,一下es5中的this,一下es6中的this,有时候自己容易晕,近期自己特意去看有关this的博客和文章,进一步加深了我对this的理解。
JS中的this,
我先把主要的两个重要的有关定义抛出来
1. this指向函数执行时启用该函数的对象,如果该函数没有被任何对象启用(绑定),this就指向window。函数在执行时,this才会进行绑定。
2.箭头函数中,this是指向定义时所在的对象。
我们常常用到构造函数,而构造函数中的this指向构造函数的实例。
function User (name,age) {
this.name = name;
this.age = age;
}
User.prototype.getName = function () {
console.log(this.name);
};
var usr1 = new User ('yang',23);
user.getName(); // yang
this是在执行时才开始绑定。因此this的指向是在执行的时候,看该函数有没有绑定对象,如果没有绑定对象,则是this指向window。
var obj = {
name: 'zhangsan',
getName: function () {
console.log(this.name)
}
}
obj.getName();// zhangsan
很显然,上面的getName函数在执行时,是被obj对象调用的。因此this指向的是obj对象。
下面改变下代码的形式:
var name = "Global";
var person = {
name: "Person",
details: {
name: "Details",
print: function () {
return this.name;
}
},
print: function () {
return this.name;
}
}
person.details.print(); //?
person.print();//?
var name1 = person.details;
var name2 = person.print;
name1.print(); //?
name2();//?
这个题很经典,我们可以逐步分析下,分析前始终要记住一句话
this指向函数执行时启用该函数的对象,如果没有任何对象启用该函数,this就指向window。函数在执行时,this才会进行绑定。
person.details.print(),很明显是被person.detail调用,返回person.details.name,即"Details"。person.print()同理和print在被person调用,返回person.name,即"Person"。
name1 = person.details,person.details 赋值给了name1,person.details的引用赋值给了name1,name1.print()也是 name1.person调用的,因此返回的结果也是"Details"。
而name2是直接被person.print函数赋值的。name2()前面没有任何东西调用它,因此name2指向的是window。
示例1:
//this指向nav
示例2:
示例3:
可能刚开始会以为结果为nav.其实不然,还是原来的那句话,this的指向,是看函数执行时而非定义时,是指向函数执行时启用该函数的对象,只要函数没被任何对象启用(绑定),this都指向window。
箭头函数中的this指向时在函数定义时的对象。
下面可以看一个
var obj = {
data: [1,2,3],
dataDouble: [1,2,3],
double: function () {
console.log("在doucle函数中");
console.log(this); // @1 表示第一个this
return this.data.map(function(item){
console.log(this); // @2 表示第二个this
return item*2;
});
},
doubleArrow: function () {
console.log("在doucleArrow函数中");
console.log(this);//@3 表示第三个this
return this.data.map((item) => {
console.log(this); // @4 表示第四个this
return item*2;
})
}
}
obj.double();
obj.doubleArrow();
obj.double(),是被obj启用的,所以在 @1和 @3 显然都是指向的obj对象。可以复制代码执行看下结果就知道了。
return this.data.map(function(item){
console.log(this); // @2 表示第二个this
return item*2;
});
this.data.map中的是匿名函数,没用被任何对象启用,因此@2指向的是window;
return this.data.map((item) => {
console.log(this); // @4 表示第四个this
return item*2;
})
箭头函数就不同了,箭头函数中的this指向定义时所在的对象,因此@4指向的是obj对象。
参考文章
http://caibaojian.com/deep-in-javascript-this.html
https://www.cnblogs.com/snandy/p/4773184.html
https://www.cnblogs.com/libin-1/p/6069031.html