4 回答
TA贡献1842条经验 获得超21个赞
var b=25;
var a={
b:20,
func: function(){
return this.b;
}
}
console.log(( a. func)())//20 A
console.log(( a. func, a.func)())//25我觉得应该都是25啊。。 B
这里涉及到2个运算符的问题,分组运算符,逗号运算符
分组运算符对于其中的表达式运算结果为reference类型的-引用类型的,不会执行取值操作
逗号运算符对其中的每一个表达式的都会执行取值操作,并且返回最有一个表达式的值作为最终的计算结果
那么对于 A 语句
(a.func)();
的左边括号就是个分组运算符,a.func属性访问表达式返回一个reference,分组运算符不对拿到的引用执行解引用操作,也就不取出实际指向的函数对象,还在a对象的环境下,接下来就对拿到的reference执行调用,此时的this还是a对象。这个和
var p=a.func;
p();
不同的,赋值运算符会对a.func求值。获取函数对象,进而赋值给p。p调用,this为为全局对象
对于 A 语句
(a.func, a.func)();
逗号运算符,对a.func都会取出实际指向的函数对象,返回这个函数对象。右边的括号为一个函数调用操作符,此时的this为全局对象。
代码改成如下也是同样的结果
(1, a.func)();
对于引用和解应用,另一个操作符delete会给出更好的理解
delete a.func;
delete操作符下,a.func的运算结果是返回一个reference而不是函数对象。也就是delete的不是指向的函数对象而是a.func本身
TA贡献1831条经验 获得超4个赞
除了this指向还有一个逗号操作符的小知识
逗号操作符依次执行返回最后一个 相当于赋给匿名值后再操作
(a.func)(); //-> a.func() a调用this为a
//逗号操作符相当于赋给匿名值后再操作
(a.func, a.func)(); //-> var c = a.func; c(); c()->window.c() window调用this为window
TA贡献1909条经验 获得超7个赞
抽象下代码,这样好分析
var a = {
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 值,都需要谨慎,譬如
var a = {
func: function() {
return this;
}
};
function f(fn) {
console.log(fn());
}
f(a.func);//window
因为函数中的参数也是按照值传递的,在向参数传递引用类型的值时,会把这个值在内存中的地址复制给一个局部变量。
添加回答
举报