#过年不停更# 说说 This 对象的理解 原创
春节不停更,此文正在参加「星光计划-春节更帖活动」
相信小伙伴们经常会听到前端面试中提到深浅拷贝的问题,这里给大家分享一下我的理解
其实我一直不理解前端JavaScript 有关this对象的理解,我也是初学,这次给大家讲解一下什么是JavaScript的this对象
为什么要用this
从前有座山,
山里有座庙叫做神庙,
神庙里面有好多和尚,
和尚们都喜欢神庙,
于是和尚们都经常挑水到神庙。
细心的朋友能发现,这里面很多神庙,非常的杂糅,不符合我们说话的喜欢,这里我们喜欢把后面出现的三个神庙变成“这”
就像在一段代码里面,如果一个变量的名字又臭又长,在后面一直使用的话,代码量不仅增加而且会使整段代码变得不整洁。
用了this后变成了这样:
this的绑定规则
1.默认绑定,函数被调用时候默认指向window,就像这样:
function demo(){
console.log(this);
}
demo(); //Window
2.隐式绑定 就像这样,具体到某一个
var boy = {
name: "leilei",
age: 23,
hight: 1.88,
detail: function () {
console.log("姓名:" + this.name);
console.log("年龄:" + this.age);
console.log("身高:" + this.hight);
}
}
boy.detail();
//输出姓名:leilei
//this.html:25 年龄:23
//this.html:26 身高:1.88
3.硬绑定:这里用到call方法,call可以调用其他函数的方法,同时还有一个aplly方法,想绑 定哪个绑定
var boyName = {
name: "小红",
sayName: function () {
console.log("我的一个朋友"+this.name);
}
}
var boy1 = {
name:"小白"
}
var boy2 = {
name:"小黄"
}
boyName.sayName.call(boy1) //小白
boyName.sayName.call(boy2) //小黄
4.构造函数绑定:
function Lover(name) {
this.name = name;
this.sayName = function(){
console.log("我的老婆是"+this.name);
}
}
var xiaohong = new Lover("小红")
xiaohong.sayName();
题目加深印象:
题目一:这道题看起来有点复杂,但是仔细分析下并不是很难,先从全局出发,有一个函数a的执行,我们在函数a里看到有函数b和函数b的执行,首先我们打印了函数b里面的this,这里默认绑定到了window所以输出window,在函数b里面有函数c和函数c的执行,这里使用了严格模式“use strict”,所以我们打印了undefined。
function a(){
function b(){
console.log(this);//window
function c(){
"use strict";
console.log(this);//undefined
}
c();
}
b();
}
a();
题目二:解析一下这道题,首先全局定义了一个name小白,然后一个方法special里面打印了一个this指向全局的name,先不着急,往下看,在定义的girl对象里面定义了一个name小红然后低有一个detail方法,下面是一个woman方法,里面定义了name小黄然后又个detail方法打印,接着看全局,首先调用了girl的detail方法,显而易见girl的detail方法里面this指向了name小红,然后是girl的woman对象里面调用了detail方法this显然指向小黄,重点是girl.special。前面说到隐式调用this是指向全局的,但是这里吧special放在了girl对象里面,this显然是指向girl对象里面的name小红,所以输出的是 “小红 小黄 小红”
var name = '小白';
function special(){
console.log('姓名:' + this.name);
}
var girl = {
name: "小红",
detail: function() {
console.log('姓名:' + this.name);
},
woman: {
name: "小黄",
detail:function(){
console.log('姓名:' + this.name);
},
},
special:special,
}
girl.detail();
girl.woman.detail();
girl.special();
题目三:解析一下,调用函数a的时候,我们先前有一个全局变量name 和函数a里面的name同名,但是函数a里面的name没有指明对象,所以这里的this指向是全局的name小红,也就是前面说的隐式调用。
在前面吧b的detail方法赋值给函数c,然后大家肯定想的是这里this指向了b里面的对象name,这个想法是不对的,这里只是赋值,只是吧b的detail方法赋给了c,就当作detail只是函数c里面的一个方法而已,在调用c的时候 this指向的还是全局,所以还是小红
接着执行b的a方法,可以看到b里面根本没有a方法,但是代码里面 b.a = a; 吧a方法赋给了方法b,所以这里b就有了a方法,然后b里面的a方法里面this指向的b方法里面name小黄,所以这里打印小黄
然后执行d(b.detail),这里的相当于在d方法里写detail一样,而且d方法里面也没有name对象,所以这里还是指向的window name小红
最后就是执行e方法,很显然这里指向的全局的window name小红不用多说,但是这里是个闭包,大家注意一下,要想了解闭包的知识可以去看看我之前写的闭包的文章
var name = "小红";
function a(){
var name = "小白";
console.log(this.name);
}
function d(i){
return i();
}
var b = {
name: "小黄",
detail: function(){
console.log(this.name);
},
bibi:function(){
return function(){
console.log(this.name);
};
},
}
var c = b.detail;
b.a = a;
var e = b.bibi();
a(); //小红
c();//小红
b.a();//小黄
d(b.detail);小红
e();//小红
总结一一下
那么关于前端this的指向就讲到这里。