Js中this指向的问题

var b=25;
var a={
b:20,
func: function(){
return this.b;
}
}
console.log(( a. func)())//20
console.log(( a. func, a.func)())//25我觉得应该都是25啊。。

阅读 3k
4 个回答
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本身

@kikong 已经说的比较完整了,我来补充下:

抽象下代码,这样好分析

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

因为函数中的参数也是按照值传递的,在向参数传递引用类型的值时,会把这个值在内存中的地址复制给一个局部变量。

一个很简单的原则判断this指向:谁调用的指向谁

console.log(( a. func)())

a调用的func所以this就是a,即this.b就是a.b,所以this.b等于20

console.log(( a. func, a.func)())
//转换成下面这两句
var c = a.func
console.log(c())

在浏览器里这个就相当于window调用的c(),所以this指向window,即this.b就是window.b,由于var b = 25b变成全局变量(window.b)所以this.b等于25

除了this指向还有一个逗号操作符的小知识
逗号操作符依次执行返回最后一个 相当于赋给匿名值后再操作

(a.func)(); //->  a.func() a调用this为a
//逗号操作符相当于赋给匿名值后再操作
(a.func, a.func)(); //->  var c = a.func; c();   c()->window.c() window调用this为window
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题