一、首先,“this”是什么?
1.this是一个关键字,所以不能用 var this、const this的声明方法。
2.说一千道一万,用一个例子表示this指的是什么:
var base_data = {//第一层,basedata
num : 12,
str : 'asdf',
base_test(){
console.log(this.str);
}
};
base_data.base_test();//执行base_test方法
上述分为两步:
(1)建立了一个base_data对象,里面包含一个num数字类型属性、一个str字符串类型属性和 base_test的方法。
(2)直接运行了base_data里面的base_test方法
最终输出如下:
>asdf
如果我们把这个方法中改为直接显示“this”,即console.log(this);则显示为:
>{ num: 12, str: 'asdf', base_test: [Function: base_test] }
由此我们可以看出,this指的就是当前所在的对象的整体,就好比一个人站在小区院里,这个人的this就是指小区。
二、多层对象相互嵌套,“this”指的是那一层?
于是我们在上述的基础上继续增加砝码,也就是嵌套一个子对象sub_data
在讨论这个问题之前,我们需要知道这个子对象sub_data套在哪里?
1.第一种方法,是对象内直接套着一个对象,如下:
var base_data = {//第一层,basedata
num : 12,
str : 'asdf',
base_test(){
},
sub_data:{//第二层,subdata
num : 24,
str : 'zxcv',
sub_test(){
console.log('第二层对象内的this改变了吗?'+this.str);
}
}
};
base_data.sub_data.sub_test();
这里我们在base_data中,嵌套了一个sub_data,如果sub_data的“this”仍然是之前的this,那么应当输出‘asdf’,如果指的是他所在的直接的对象,那就应该是subdata的str,也就是'zxcv'。
运行结果:
>第二层对象内的this改变了吗?zxcv
果然,变了。此时this已经代指sub_data了。
2.另辟蹊径,在第一层base_data中的方法里面声明一个sub_data:
var base_data = {//第一层,basedata
num : 12,
str : 'asdf',
base_test(){
var sub_data={//第二层,subdata
num : 24,
str : 'zxcv',
sub_test(){
console.log('第二层对象内的this改变了吗?'+this.str);
}
};
return sub_data.sub_test();
//这里需要把子对象sub_data中的sub_test伸出来,
//也就是在base_test中return一个sub_data.sub_test()
}
};
base_data.base_test();
执行结果如下:
>第二层对象内的this改变了吗?zxcv
果然,还是变了。
从上述两种情况来看,所谓的this,指的就是最直接存在的那个对象整体。如果你站在小区院里,那么你的“this”只的就是整个小区;但是如果你站在单元楼走廊里面,你的this就是指你的单元楼;如果你站在家里,那么你的this就是你的家。
三、“that = this”有什么意义?
this是一个关键字,我们没有办法手动定义,它的意义会随着位置改变,好比刻舟求剑一样,类似于一个相对位置。
这时,我们可以声明一个变量。当我需要一个相对固定的引用,比如我来到了第十八层子对象,仍然向调用第一层对象中的属性或方法,那么我们就可以定义一个that(毕竟that不是一个关键字啊),方法如下:
var base_data = {//第一层,basedata
num : 12,
str : 'asdf',
base_test(){
var that = this;
//注意,这里定义了that,相当于一个锚点
var sub_data={//第二层,subdata
num : 24,
str : 'zxcv',
sub_test(){
console.log('第二层对象内的that改变了吗?'+that.str);
}
};
return sub_data.sub_test();
}
};
base_data.base_test();
这时候输出为:
第二层对象内的that改变了吗?asdf
此处输出的结果为asdf,成功地获取了锚定位置的this。不论以后有多少层的subsubsubsub_data,既然在base_data中锚定了that,之后调用that就永远是base_data的数据了。
当然,也可以that1,that2这样多处锚定,但这是一个不好的习惯,容易堆成屎山。。。
四、总结
通过上述的例子,总结了一个经验:
this是一个关键字,是会随着不同位置而具有不同的意义,是一种相对位置。
that是我们定义的变量,将所调用的位置固定下来,成为绝对位置。