ES6箭头函数(二)-this绑定

箭头函数,除了帮助我们简写之外,最大的好处就是this不再被绑定在调用者,而是继承与环境对象,在哪个环境定义,this就是指的哪个环境对象。

在编写构造函数或者函数时,this的指向经常会变化,导致this.属性无法在各个函数体面使用

案例代码:

    function Counter() {
        console.log('我是构造体'+this);
        this.number = 0;
​
        //返回一个 ID(数字),可以将这个ID传递给 clearTimeout() 来取消执行。        
        this.timer = window.setTimeout(function () {
            this.number++;
            //此时的this的意思是window,window是没有number属性的
            console.log(this.number);
        },1000)
    }
​
    var b = new Counter();
    console.log(b.number);
    结果 0
         NaN

为了解决this指向问题,我们可以使用bind来改变,不能使用call,apply

    function Counter() {
        this.number = 0;
        var fn = function () {
           this.number++
            console.log(this.number);
        }
        // 不能用call、applay,这两种方法都是立即执行,并且不会循环执行
        // var timer =  window.setTimeout(fn.call(this),3000)
        //var timer =  window.setInterval(fn.apply(this),3000)
        var timer =  window.setInterval(fn.bind(this),3000)
    }
​
    var b = new Counter();
    console.log(b.number);

从上可以看出,想改变this的指向非常困难

有了箭头函数之后,一切都变得简单,不在绑定this的指向了

    function Counter() {
        this.number = 0;
        var timer = setInterval(() => {
            console.log(this);
            this.number++;
            console.log(this.number);
        },2000)
    }
​
    var b = new Counter();

原理分析:

普通函数,this的概念是:this是JavaScript的一个关键字,他是指函数执行过程中,自动生成的一个内部对象,是指当前的对象,只在当前函数内部使用。(this对象是在运行时基于函数的执行环境绑定的:在全局函数中,this指向的是window;当函数被作为某个对象的方法调用时,this就等于那个对象)。

 

函数中this对象的取值,是在函数被调用执行的时候确定的。此时会创建执行上下文环境。

对于箭头函数,它没有自己的this,不能用作构造函数。

箭头函数中的this对象是定义时所在的对象,不是调用时所在的对象。

案例1

    var testObject = {
        name:'123',
        sayHi:function () {
            console.log(this);
            // return function () {
            //     console.log(this);
            // }
            //箭头函数的this,不再是谁调用就是谁,而是指当前环境的this是谁,
            //一般是指父级,因为箭头函数没有this对象,都是从父级继承过来的
            return ()=>{
                console.log(this);
            }
        }
    }
​
    var hh = testObject.sayHi();
    window.hh();

案例2

    function foo() {
        setTimeout(function() {
            console.log('setTimeout普通函数的this='+this);
            console.log("id: ",this.id);
        }, 100);
    }
    function fooa() {
        setTimeout(()=>{
            console.log('setTimeout箭头函数的this='+this);
            console.log("id: ",this.id);
        }, 100);
    }
    var id=21;
    //两个函数的结果都是一样的:window,21
    //因为可以理解为都是由window调用的window.foo() 和 window.fooa()
    foo();  //this指向window对象, 21
    fooa(); //this指向window对象, 21
​
    =========================================
    //setTimeout(普通函数体)的this指向的调用时对象,那么这个对象如果不改变的话永远都是window.
    foo.call({id:42}); //this指向window对象, 21
   //setTimeout(箭头函数体)本身没有this,定义时对象,也就是哪个对象调用了,this就是哪个对象的
    fooa.call({id:42}); //this指向object对象, 42
​

案例3-返回值是函数的,函数体里面的this指向的是window,和普通函数里面的this一样

const test = {
  name: 'test object',
  createAnonFunction: function() {
    return function() {
      //function 当做了普通函数,this的指向是window
      console.log(this.name);
      console.log(arguments);
    };
  },
 
  createArrowFunction: function() {
    return () => {
      //箭头函数本身没有this对象,this是在定义是去找,本身没有的话,就会去父级寻找
      //当test对象去调用方法createArrowFunction,this就获得了test对象
      console.log(this.name);
      console.log(arguments);
    };
  }
};
//结果
JavaScript 代码:
> const anon = test.createAnonFunction('hello', 'world');
> const arrow = test.createArrowFunction('hello', 'world');
 
> anon();
undefined
{}
 
> arrow();
test object
{ '0': 'hello', '1': 'world' }

案例4-函数作为参数的时候,函数体里面的this指向的是window,和普通函数里面的this一样

    Array.prototype.myFind = function (index,callback) {
        //this是对象数组
        console.log(this)
        for (var i = 0; i < this.length; i++) {
            if(i === index){
                callback(this[i])
            }
        }
    }
    var arr = ['hello', 'WORLD', 'Whatever'];
    arr.myFind(1,function (item) {
        //this是window
        console.log(this);
        console.log(item);
    })
特殊的案例
 Array.prototype.myFind = function (index, callback) {
​
        for (var i = 0; i < this.length; i++) {
            if (i === index) {
                callback.call(this,this[i])
                //callback(this[i])
            }
        }
    }
 
    var arr = ['hello', 'WORLD', 'Whatever'];
    arr.myFind(1, function (item) {
        //array数组
        console.log(this);
​
    })
​
    arr.myFind(1, item => {
        //window对象
        console.log(this);
    })
   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值