学习总结:JavaScript之this作用域
前言
之前一直对js的this作用域处于一个懵懵懂懂的状态,找了个机会看了一些视频跟其他大佬的文章系统的了解补充了一下this作用域知识,然后做了一些学习总结,也是第一次写博客,欢迎大佬们交流经验指出不足。
this作用域
1、定义
每一个行为发生的时候,肯定会有一个发生这个行为的主体。这个主体就是this。
this指代的是当前对象,即正在执行这个(包含this)函数的对象。
也就是说,谁调用这个函数,this就指向谁。
往下看例子
2、this的指向问题
上面说到 谁调用这个函数,this就指向谁
被全局对象调用,this指向全局对象(window)
var value = 'aaa'
function lx () {
let value = 'bbb';
console.log(this.value);
}
lx(); // aaa
// 等同于window.lx();被window调用,指向window。
在构造函数中,this指向实例
(ps:构造函数会生成并返回一个新的对象,this就指向那个对象)
function Lx () {
this.value = 'bbb';
}
let xx = new Lx(); // this指向new lx(),也就是指向xx
console.log(xx.value); // bbb
谁调用这个函数,this就指向谁
下面这个例子就很清晰了,由xx调用,所以this指向xx
var value = 'aaa'
let xx = {
value: 'bbb',
print: function () {
console.log(this.value);
}
}
xx.print();// bbb
接下来我们看这个例子
var value = 'aaa'
var xx = {
value: 'bbb',
print: function () {
console.log(this.value)
}
}
var jj = {
value: 'ccc',
zz: {
value: 'ddd',
print: function () {
console.log(this.value);
}
}
}
xx.print(); // bbb
window.xx.print(); // bbb
jj.zz.print(); // ddd
这个时候出现一个问题
为什么window.xx.print();没有指向window
为什么jj.zz.print(); 没有指向jj
总结下来:
1、如果一个函数中有this,并且它没有被上一级的对象调用,那么this指向window。
2、如果一个函数中有this,并且它被上一级对象调用,那么this指向上一级对象。
3、如果一个函数中有this,并且包含多个对象,即使它被最外层的对象调用,this也仅指向它的上一级对象。这个跟我们前面说的谁调用这个函数,this就指向谁有些许差异,需要再理解消化。
我们再看两个例子
var value = "aaa";
let xx = {
value: "bbb",
print: function () {
/*
return function () {
console.log(this.value);
}
*/
// 为了方便理解我写成这样
var jj = function () {
console.log(this.value);
}
return jj;
}
}
xx.print()(); // aaa
首先,xx.print()是一个函数,执行后返回jj函数,所以xx.print()()等同于jj()等同于window.jj(),所以对象中有2层或以上的方法时,this指向全局对象;
var xx = {
value: "aaa",
jj: {
value: "bbb",
print: function () {
console.log(this); //window
}
}
}
var zz = xx.jj.print;
zz();
this永远指向最后调用它的对象,函数print赋值给zz的时候并没有执行,所以this不是指向jj,最终执行的时候是由zz()也就是window.zz(),所以this指向全局对象。
将上一个例子加工一下,变成一个立即执行函数
var value = "aaa";
let xx = {
value: "bbb",
print: (function () {
return function () {
console.log(this.value);
}
})()
}
xx.print(); // bbb
为什么它不像前面那个例子一样指向window呢,作为一个立即执行函数,他已经被调用并且返回函数,这个函数是被xx调用,所以指向了xx。
说说定时器中的this
setTimeout(function(){
console.log(this);
}, 300)
以这个简单的定时器为例,定时器中的函数会放在全局,被window调用,所以定时器中的this指向全局对象
再说说箭头函数
let xx = {
value: "aaa",
print: () => {
console.log(this.value);
}
}
xx.print(); // undefind
按照很多书籍跟例子的说法,箭头函数没有this,this会指向当前函数的上一层作用域(定义时所处的作用域),所以上述例子指向的是全局对象。
那么我们把箭头函数放到定时器中
let xx = {
value: "aaa",
print: function () {
setTimeout(() => {
console.log(this.value)
}, 300)
}
}
xx.print(); // aaa
这时候当前函数的上一层作用域是xx,这个this就指向了xx,最简单的判断方法就是当这个箭头函数不存在,那么根据前面的规则,this该指向谁就指向谁。
关于改变this的指向问题找个时间再继续写,学习借鉴了很多大佬的文档跟视频,做的学习总结,欢迎各位大佬交流指正。