• 箭头函数中的this指向


    最近做的项目中遇到了在箭头函数里使用this时报错的问题,把箭头函数的写法改成function()后,this的指向才达到预期。关于这个问题值得研究一下。

    在箭头函数出现之前的ES5时代,this指向它的调用者。是哪个对象调用了这个属性或方法,this就指向这个对象。这有点像“我”这个人称代词,是从谁的嘴里说出了“我”,这个“我”就指代了谁。

    一个简单的例子:

    // 用var定义的变量,this指向window
    // 调用sayName()等于调用this.sayName()等于调用window.sayName()
    var name = 'window';
    var sayName = function(){
      return this.name
    }
    console.log(sayName()) 			//window
    console.log(this.sayName()) 	//window
    console.log(window.sayName()) 	//window
    
    // 用obj调用的sayName方法,其中this指向调用它的obj
    var obj = {
      name : 'obj',
      sayName : function(){
    	return this.name
      }
    }
    console.log(obj.sayName()) 	    //obj
    

    后来ES6规范中的箭头函数里面的this是在定义它时绑定的,指向它的父级作用域,而不是调用它对象,这个this的指向是不能通过call和apply改变的。

    箭头函数在对象字面量中的this指向:

    // 用var定义的变量,this指向window
    // 虽然展现结果和上例一样,但是this的指向绑定的时机是有区别的,箭头函数在定义时已经绑定,普通函数只会在调用时确定
    var name = 'window';
    var sayName = () => {
      return this.name;			//this指向window
    };
    console.log(sayName());         //window
    console.log(this.sayName());    //window
    console.log(window.sayName());  //window
    
    //同样用obj调用的sayName方法,this指向父级作用域window
    var obj = {
      name: 'obj',
      sayName: () => {
        return this.name;  
      }
    };
    console.log( obj.sayName() );     //window
    console.log( obj.sayName() === window.sayName() );     //true
    

    这是箭头函数this指向在对象字面量中的行为。多说一句,在用对象实例调用时会有所差别。

    看下面的例子:

    var name = 'window'
        
    function Obj(name){     //构造函数Obj
      this.name = name;
      this.s1 = function(){
        return this.name;   //普通函数方法,this指向Obj
      }
      this.s2 = () => {
        return this.name;   //箭头函数方法,this还是指向Obj,因为构造函数function Obj(name)形成了一级作用域
      };
    }
    Obj.prototype.s3 = function(){
      return this.name;     //原型链上的普通方法,this指向实例obj1的构造函数Obj
    }
    Obj.prototype.s4 = () => {
      return this.name;     //原型链上的箭头函数,定义它的时候,这个箭头函数的父级作用域是window
    }
    
    //实例化对象
    const obj1 = new Obj('obj');
    
    console.log(obj1.s1());  //obj
    console.log(obj1.s2());  //obj
    console.log(obj1.s3());  //obj
    console.log(obj1.s4());  //window
    
    • s2()箭头函数会去找定义它时的父级作用域,因为构造函数Obj也是个函数,它会形成自己的作用域。定义s2()的时候父级作用域变成了构造函数Obj所在的域
    • s4()和s2()的区别是s4()挂载到构造函数的原型上了,定义s4()的时候,这个箭头函数的父级作用域是window,所以用实例调用方法会输出了 'window'

    最后总结:在对象字面量中和在构造函数的原型上使用箭头函数,this指向不是我们预期的结果,在这两种情况下使用箭头函数要慎重。

  • 相关阅读:
    今晚直播 | 揭秘携程应用路由生态系统
    OpenStack虚拟云桌面在携程呼叫中心的应用
    从设计到开发,硅谷技术专家教你做“声控”APP
    深度学习系列 | 诺亚面向语音语义的深度学习研究进展
    知识图谱中的推理技术及其在高考机器人中的应用
    用户在线广告点击行为预测的深度学习模型
    知识库上的问答系统:实体、文本及系统观点
    深度学习在搜狗无线搜索广告中的应用
    元旦三天假期,实现一个电商退单管理系统【四】-手机客户端实现
    元旦三天假期,实现一个电商退单管理系统【三】
  • 原文地址:https://www.cnblogs.com/sonicwater/p/12028929.html
Copyright © 2020-2023  润新知