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

Js中this指向的问题

Js中this指向的问题

素胚勾勒不出你 2019-03-05 10:35:49
var b=25;var a={b:20,func: function(){return this.b;}}console.log(( a. func)())//20console.log(( a. func, a.func)())//25我觉得应该都是25啊。。
查看完整描述

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本身


查看完整回答
反对 回复 2019-03-14
?
慕容708150

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


查看完整回答
反对 回复 2019-03-14
?
jeck猫

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

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


查看完整回答
反对 回复 2019-03-14
  • 4 回答
  • 0 关注
  • 538 浏览
慕课专栏
更多

添加回答

举报

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