「这是我参与2022首次更文挑战的第28天,活动详情查看:2022首次更文挑战」。
javascript中的this指向是十分重要的,同时也是难以理解。这次我对this的指向问题做个学习总结。
this的作用
我们创建一个对象,对象中有name属性和eating、running、studying方法,如果想要在这些方法中拿到name属性,我们就可以使用this,这里的this代表的是obj对象。
var obj = {
name: 'haha',
eating: function() {
console.log(this.name + '在吃东西');
},
running: function() {
console.log(this.name + '在跑步');
},
studying: function() {
console.log(this.name + '在学习');
}
}
obj.eating()
obj.running()
obj.studying()
那么我们不使用this可以在这方法中拿到obj对象的name属性吗?
eating: function() {
// console.log(this.name + '在吃东西');
console.log(obj.name + '在吃东西');
},
running: function() {
// console.log(this.name + '在跑步');
console.log(obj.name + '在跑步');
},
studying: function() {
// console.log(this.name + '在学习');
console.log(obj.name + '在学习');
}
我们可以通过obj.name获取到name属性。从某些角度来说,开发中如果没有this,很多问题我们也是有解决方案的。但是没有this,会让我们编写代码非常不方便。
我们新创建一个info对象,复制上面的代码,就需要把对象中的log中的obj改成info。这是相当的麻烦。
var info = {
name: 'haha',
eating: function() {
console.log(info.name + '在吃东西');
},
running: function() {
console.log(info.name + '在跑步');
},
studying: function() {
console.log(info.name + '在学习');
}
}
info.eating()
info.running()
info.studying()
但是有了this之后,我们只需要修改变量名就行,不需要修改对象中的内部代码。
var info = {
name: 'haha',
eating: function() {
console.log(this.name + '在吃东西');
},
running: function() {
console.log(this.name + '在跑步');
},
studying: function() {
console.log(this.name + '在学习');
}
}
info.eating()
info.running()
info.studying()
this的指向
this在全局作用域的指向
在全局作用域下,this指向根据运行环境的不同也会不同。在浏览器环境中,this指向的是window(globalObject)。在node环境中,this指向的是空对象{}。在node环境中,node执行js文件的时候会把这个文件当做一个模块module,然后加载这个模块。加载之后,会编译我们的代码,编译完之后,会把我们所有的代码放在一个函数中,然后执行这个函数.call({}),把this指向空对象{}。
我们在浏览器环境中执行以下代码。
console.log(this);
console.log(window);
我们可以看到浏览器环境中的this指向的是window。
我们在node环境中执行以下代码,在node环境中是没有window的。
console.log(this);
this在函数中的使用
我们通常在函数中使用this,很少直接在全局作用域下去使用this。
- 所有函数在被调用时,都会创建一个函数执行上下文。
- 这个上下文中记录着函数的调用栈、AO对象等。
- this也是其中的一条记录。 需要注意的是,this指向什么,跟函数所处的位置是没有关联的,但是跟函数被调用的方式是有关系。
我们可以通过不同的方式调用函数,this指向就不同。
function foo() {
console.log(this);
}
// 1. 直接调用这个函数
foo()
// 2.创建一个对象,对象中的函数指向foo
var obj = {
name: 'haha',
foo: foo
}
obj.foo()
// 3. apply调用
foo.apply('abc')
我们在浏览器中运行以上代码,可以看到,定义一个函数,采用不用的方式对它进行调用,this会有不同的指向。
我们可以得出以下结论:
- 函数在调用时,JavaScript会默认给this绑定一个值
- this的绑定和函数定义的位置(编写的位置)没有关系
- this的绑定和调用方式以及调用的位置有关系
- this是动态绑定的,即是在运行时被绑定的