浅谈对this的理解

189 阅读1分钟

一、this的理解

第一准则: this 永远指向函数 运行时 所在的对象,而不是函数被创建时所在的对象【不包含箭头函数】

二、this 的集中指向:

  1. window 对象 如: console.log(this);
  2. 函数中的 this 函数中的this,谁调用函数,函数中的 this 就指向谁,一般指向 window 如: function foo() { console.log(this); } foo();
  3. 对象中的 this ,一般指向对象 如: var obj = { name: "jack", run: function() { console.log(this.name+"run"); } } obj.run();

变式.png 4. 构造函数中的 this, 指向实例化出来的对象 function Person(name) { this.name = name; // this 指向当前实例化的对象。 }'

三、借来的 this (难点)

可以借助一些方法手动修改 this 的指向。

1、fn.call(对象, 参数1, 参数2...) 【将函数的上下文环境切换到另外一个对象中】【参数利用逗号隔开,如"小乔","一天"】 注意: 该函数会立即执行; 执行一次。 如:

var p1 = {
name: "小姐姐",
phone: function(name) {
console.log(this.name + “给” + name + "打电话")
}
}
p1.phone("小乔");
var p2 = {
name: "曹操"
}
p1.phone.call(p2, "杨修");	// 函数.call(对象, 参数1, 参数2...)

2、fn,apply(对象, [参数1, 参数2...]) 用法同 call ,只是传参方式不一样。

p1.phone.apply(p2, ["杨修","两天"]);	// 函数.apply(对象, [参数1, 参数2...])
p1.phone("小乔","一年");//上方借的方法都是临时性的,该方法还是属于p1

3、 fn.bind(对象) 用于被动修改 this 的指向【一般用于修改回调函数的方法】

bind.png 总结:call 、apply 、bind 的区别

相同点: 都是用于改变函数中 this 的指向。

不同点:

  1. call 、apply 都是立即执行(主动),用于一般函数
  2. bind 是被动执行,通常用于回调函数
  3. call 直接将参数举例在对象的后面
  4. apply 是以数组的形式传递参数

代码示例如下

<script>
    /* 
      1、this 理解
        第一准则: this 永远指向函数运行时所在的对象,而不是函数被创建时所在的对象。(不包含箭头函数)

      2、this 的几种指向:
        2.1 window 对象
    */  
    console.log(this);

    /* 
      2.2 函数中的 this
        函数中的 this,谁调用函数,函数中的 this 就指向谁,一般指向 window。
    */
    function foo() {
      console.log(this);
    }
    foo(); // === window.foo() , window

    /* 
      2.3 对象中的 this,一般指向对象
    */
    var obj = {
      name: "jack",
      run: function() {
        console.log(this.name + " 跑得快。");
      }
    };
    obj.run();

    // 变式
    window.name = "window";
    // var obj = {
    //   name: "jack",
    //   run: function() {
    //     console.log(this.name);
    //     window.setTimeout(function() {
    //       console.log(this.name + " 跑得快。");
    //     }, 1000);
    //   }
    // };
    // obj.run();

    /* 
      2.4 构造函数中的 this,指向实例化出来的对象。
    */
    function Person(name) {
      this.name = name;
    }
    var p1 = new Person("jack");

    /* 
      3、借来的 this(难点)
        可以借助一些方法手动修改 this 的指向。

        >> fn.call(对象, 参数1, 参数2...):将函数的上下文环境切换到另一个对象中
          注意:
            该函数会立即执行;
            执行一次;
            临时性的。
    */
    var p1 = {
      name: "周瑜",
      phone: function(name, time) {
        console.log(this.name + "给" + name + "打了" + time + "的电话");
      }
    }
    p1.phone("小乔");

    var p2 = {
      name: "曹操"
    }
    // p1.phone.call(p2, "杨修");
    p1.phone.call(p2, "小乔", "一天");

    /* 
      >> fn.apply(对象, [参数1, 参数2...])
        用法同 call,只是传参方式方式不一样。
    */
    p1.phone.apply(p2, ["大乔", "一个星期"]);

    p1.phone("小乔", "一年"); // 上方借的方法都是临时性的,该方法还是属于 p1

    /* 
      >> fn.bind(对象):被动修改 this 的指向,一般用于修改回调函数的 this 指向。

      >> call、apply、bind 的区别:
        相同点:都是用于改变函数中 this 的指向。

        不同点:
          * call、apply 都是立即执行(主动),用于一般函数;
          * bind 是被动执行,通常用于回调函数;
          * call 直接将参数列举在对象的后面;
          * apply 是以数组的形式传递参数。
    */
    var obj = {
      name: "jack",
      run: function() {
        setTimeout(function() {
          console.log(this.name + " 跑得快。");
        // }.bind(obj), 1000);
      }.bind(this), 1000);
      }
    };
    obj.run();
  </script>