• this的理解


    记录一下自己关于this的理解

    1.this的官方说法---参考JavaScript高级程序设计语言
    this对象是在运行时基于函数的执行环境绑定的。也就是说,this代表的是函数执行时,所运行环境的主体对象。

    2.this设计的目的--参考阮一峰日志
    函数一经创建,会存在内存中,赋值给变量的是函数在内存中的地址。这样函数在各种环境中就是一个单独的值,可以在不同环境中执行。因此需要有一种机制,能够在函数体内部获得当前的运行环境,以便于获取当前环境中的数据(个人理解)。

    3.this的指向(个人理解)
    我们所说的this指向,也就是this代表谁,绑定给了谁。我所理解地就是,this代表了函数被调用时,调用这个函数的对象,就是点前面的那个对象。
    例如:window.fn() obj.fn(),前者是函数正常调用时,指向了window这个对象,后者是方法调用时,指向了这个调用方法的obj对象,它们都是点前面的对象。当然这只是一般情况下而言。

    4.this的调用模式
    我们都知道,this在函数刚被定义的时候,是没有任何意义的,只有函数在执行时(被调用),才会绑定执行主体,即确定指向,那么就可以通过函数的调用模式来确定this是如何确定指向的。

    ①函数调用模式,即普通的函数调用,this指向window

      var name = "bobo"
      function global(){
      var name = "lele"
       console.log(this.name)
      }
      global(); // "bobo" this指向window,thi.name就是window.name
    
      只要是函数单独调用,前面没有点的,都是函数调用模式,this指向window.例如:
    
      var name = "bobo"
      var obj = {
        name: 'lele',
        say: function () {
          console.log('hi,' + this.name);
        },
      };
      obj.say(); // hi,lele
      var sayHi = obj.say;
      sayHi(); // hi,bobo,sayHi被赋值了say方法的函数地址,本身已经是一个独立的函数,在执行时跟定义在全局中的函数一样,都是被window调用
    

    ②方法调用模式,即定义在对像中的方法是一个函数,当方法被调用时,就是该函数被调用

    在上面的例子中已经写了,调用obj对象中的say方法时,方法中的this指向的是obj这个对象,所以this.name相当于是obj.name,结果是hi,lele
    但是,方法调用模式中,我们常常迷惑的不是这么简单的调用,而是当出现多层调用时,this到底指向的是哪一层的调用对象,例如:

      var obj = {
        name: 'bobo',
        first: {
          name: 'lele',
          second: {
            name: 'mingming',
            say: function () {
              console.log('hi,' + this.name);
            },
          },
        },
      };
      obj.first.second.say(); // hi,mingming  this指向了second
    
      由此可见,this最终指向的是最后调用它的那一级对象,这里我用自己的理解方式,this指向的就是最终找到它的那个对象。
    

    ③构造函数调用模式

    构造函数中的this,是由于new的作用,将this指向了它创建的实例对象

      function Person() {
        this.name = 'bobo';
        this.age = '23';
        this.say = function () {
          console.log('hi,bobo');
        };
      }
      var p = new Person();
      console.log(p.name); // bobo
    

    这个应该比较容易理解,因为new已经帮我们确定好了this到底绑定给了谁,那就是new创造的实例对象。

    ④apply,call,bind方法调用,又叫做上下文调用

    apply,call,bind是函数的方法,函数调用该方法之后,通过传参可以改变函数内部的this指向。

      var bobo = {
        hobby: '滑板',
        say: function () {
          console.log('我喜欢' + this.hobby);
        },
      };
      var lele = {
        hobby: '唱歌',
      };
      bobo.say(); // 我喜欢滑板
      bobo.say.apply(lele);// 我喜欢唱歌
      bobo.say.call(lele);// 我喜欢唱歌
      var leleSay = bobo.say.bind(lele); 
      leleSay();// 我喜欢唱歌
    

    这三种方法都可以改变函数内部的this指向,但是又有所不同,这里对它们的区别暂时不做讨论。
    这种方法我觉得应该叫做借用模式,就是通过改变this指向,使this指向的这个对象借用到这个方法,从而来获取该对象内的数据。

    ⑤特殊情况下的this指向

    例如:事件函数内的this指向的是事件源,setTimeout setInterval 指向的是window,匿名函数的自调用(立即执行函数)指向window。
    另外:在严格模式下,没有显示函数的调用主体时,即在函数调用模式下,不再指向window,而是指向undefined。

    ⑥箭头函数里面的this指向

    箭头函数里面没有定义this,因此箭头函数里面写有this时,就会按照作用域链去查找有定义this的那一级作用域的this,这时的this就指向调用这个作用域函数的调用者。

      var id = 3;
      function foo() {
        var id = 2;
        // var that = this;
        //var this
        setTimeout(() => {
          console.log('id:', this.id);
        }, 100);
      }
      foo(); // id=2; 箭头函数没有定义this,所以this应该时foo函数中的this,而foo是window调用的,因此this指向window
    
      var obj = {
        id: 4,
        time: function () {
          var id = 5;
          var aa = {
            bb: () => {
              console.log('id:', this.id);
            },
          };
          aa.bb();
        },
      };
       obj.time(); // id=4,这时的this按照作用域查找,是time方法中的this,time方法被obj调用,this就指向obj
    

    总结目前到这里,有新的发现,或者发现理解上的错误,再来修改。加油!

  • 相关阅读:
    mongodb(2)
    mongodb(1)
    分片集群
    副本集 集群
    java连接腾讯云上的redis
    maven打包
    生成ftp文件的目录树
    从ftp获取文件并生成压缩包
    android 连续点击退出程序
    Android之完美退出方法
  • 原文地址:https://www.cnblogs.com/mandymm/p/13955746.html
Copyright © 2020-2023  润新知