zoukankan      html  css  js  c++  java
  • 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);
    
        })
    特殊的案例
  • 相关阅读:
    非常不错的学习网站——技术胖
    Vue中使用mescroll.js实现下拉刷新
    2020.10.07【NOIP提高A组】模拟
    2020.10.06【NOIP提高A组】模拟 总结
    2020.09.19【NOIP提高A组】模拟
    2020.09.12【NOIP提高A组】模拟
    GMOJ 4417. 【HNOI2016模拟4.1】神奇的字符串 题解
    上下界网络流学习笔记
    GMOJ 3571. 【GDKOI2014】内存分配 题解
    [模板]人工栈
  • 原文地址:https://www.cnblogs.com/MoonASixpence/p/14292960.html
Copyright © 2011-2022 走看看