为了账号安全,请及时绑定邮箱和手机立即绑定

Js中this指向的问题

Js中this指向的问题

慕后森 2019-05-23 19:34:25
varb=25;vara={b:20,func:function(){returnthis.b;}}console.log((a.func)())//20console.log((a.func,a.func)())//25我觉得应该都是25啊。。
查看完整描述

2 回答

?
ABOUTYOU

TA贡献1812条经验 获得超5个赞

varb=25;
vara={
b:20,
func:function(){
returnthis.b;
}
}
console.log((a.func)())//20A
console.log((a.func,a.func)())//25我觉得应该都是25啊。。B
这里涉及到2个运算符的问题,分组运算符,逗号运算符分组运算符对于其中的表达式运算结果为reference类型的-引用类型的,不会执行取值操作逗号运算符对其中的每一个表达式的都会执行取值操作,并且返回最有一个表达式的值作为最终的计算结果那么对于A语句
(a.func)();
的左边括号就是个分组运算符,a.func属性访问表达式返回一个reference,分组运算符不对拿到的引用执行解引用操作,也就不取出实际指向的函数对象,还在a对象的环境下,接下来就对拿到的reference执行调用,此时的this还是a对象。这个和
varp=a.func;
p();
不同的,赋值运算符会对a.func求值。获取函数对象,进而赋值给p。p调用,this为为全局对象
对于A语句
(a.func,a.func)();
逗号运算符,对a.func都会取出实际指向的函数对象,返回这个函数对象。右边的括号为一个函数调用操作符,此时的this为全局对象。代码改成如下也是同样的结果
(1,a.func)();
对于引用和解应用,另一个操作符delete会给出更好的理解
deletea.func;
delete操作符下,a.func的运算结果是返回一个reference而不是函数对象。也就是delete的不是指向的函数对象而是a.func本身
                            
查看完整回答
反对 回复 2019-05-23
?
沧海一幻觉

TA贡献1824条经验 获得超5个赞

@kikong已经说的比较完整了,我来补充下:
抽象下代码,这样好分析
vara={
func:function(){
console.log(this);
}
};
a.func();//1、a
(a.func)();//2、a
(a.func,a.func)();//3、window;
(a.func=a.func)();//4、window;
这里其实就是this的指向问题;
1、在方法调用(如果某个对象的属性是函数,这个属性就叫方法,调用这个属性,就叫方法调用)中,执行函数体的时候,作为属性访问主体的对象和数组便是其调用方法内this的指向。通俗的说,调用谁的方法this就指向谁;)
2、虽然加上括号之后,就好像只是在引用一个函数,但this的值得到了维持,因为a.func()和(a.func())的定义时相同的,按照kikong所说,就是()不对拿到的引用执行解引用操作,也就不取出实际指向的函数对象,还在a对象的环境下,接下来就对拿到的reference执行调用,此时的this还是a对象。
3、4、其实一样,逗号运算符、赋值运算符都返回一个值,也就是保存在内存中的函数本身,所以this的值不能得到维持,这是因为
this对象是在运行时基于函数的执行环境绑定的:在全局函数中,this等于window(浏览器非严格模式,严格模式是undefined)
上面四个明白了,上面的题目就解开了;this更多了解戳这
这里有个引申,按照上面的逻辑,所有返回值操作的,都有可能去改变上面代码中的this值,都需要谨慎,譬如
vara={
func:function(){
returnthis;
}
};
functionf(fn){
console.log(fn());
}
f(a.func);//window
因为函数中的参数也是按照值传递的,在向参数传递引用类型的值时,会把这个值在内存中的地址复制给一个局部变量。
                            
查看完整回答
反对 回复 2019-05-23
  • 2 回答
  • 0 关注
  • 260 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信