this指向

文章详细解析了JavaScript中this关键字在不同情况下的行为,包括默认绑定、隐式绑定的丢失、显式绑定(call/bind/apply)、new绑定以及箭头函数的this特性,还探讨了构造函数和setTimeout函数中的this指向。
摘要由CSDN通过智能技术生成
  <script>
var a = 'window';

    /************************************
       01: 默认绑定 => 指向全局对象
       strict mode 严格模式 undefined
    ***************************************/
    function defaultFn() {
      console.log(this.a);
    };
    defaultFn(); // 2


    /************************************
        02: 隐式绑定
    ***************************************/
    function hideFoo() {
      console.log(this.a);
    }
    var hideObj = {
      a: 2,
      say: hideFoo
    };
    hideObj.say(); // 2 => say函数的调用对象是obj


    var obj1 = {
      a: 100,
      hideObj: hideObj,
      hideFoo: hideFoo
    };
    obj1.hideObj.say(); // 2 => this是hideObj
    obj1.hideFoo()  // 100 => this是obj1


    /************************************
        03: 隐式绑定丢失
    ***************************************/
    function hideLostFoo() {
      console.log(this.a);
    }
    var hideLostObj = {
      a: 2,
      hideLostFoo: hideLostFoo
    };
    var bar = hideLostObj.hideLostFoo;
    bar(); // this是window => 等价 hideLostFoo自调用

    function foo1() {
      console.log(this.a);
    }
    function doFoo(fn) {
      fn();
    }
    var obj = {
      a: 2,
      foo: foo1
    };
    doFoo(obj.foo); // this是window => 等价 foo1自调用


    /************************************
        04: 显式绑定 call,bind,apply
    ***************************************/
    function foo1(arg1, arg2) {
      console.log(this, arg1, arg2);
      console.log(this.a, arg1, arg2, '显式绑定');
    }
    var obj = {
      a: 2
    };
    // foo1.call(obj,'参数1'); 
    // foo1.apply(obj,['参数2']); 
    // foo1.bind(obj, ['参数2'])(100);  // bind 返回的是一个函数
    foo1.call('字符串'); // 简单类型 => 会被默认处理(装箱) new String(arg) new Number(arg)


    
    /************************************
    05: new绑定
       I. 创建(或者说构造)一个全新的对象。
      II. 这个新对象会被执行 [[ 原型 ]]  连接。
     III. 这个新对象会绑定到函数调用的 this。
      IV. 如果 [ 函数没有返回其他对象 ],那么 new 表达式中的函数调用会自动返回这个新对象
    ***************************************/
    function fq(a) {
      this.a = a;
    };
    fq.prototype.say = function () {
      console.log(this.a);
    }
    var bar = new fq(2);
    console.log(bar.a); // 2

    // 模拟new 过程
    function fq(a) {
      const obj = {};
      obj.a = a;
      Object.setPrototypeOf(obj, fq.prototype)
      return obj;

      // 或者
      //   var obj = Object.create(fq.prototype);
      //   obj.a = a;
      //   return obj;
    }
    fq.prototype.say = function () {
      console.log(this.a);
    }


    /************************************
      06: 箭头函数绑定
      箭头函数没有自己的this,
      箭头函数的 this 始终会捕获和继承自其定义时【所处的外层作用域的 this 值】
    ***************************************/
    const ms = {
      a: 10,
      say: () => {
        console.log(this.a);
      },
      say1(){ // ★不是箭头函数(object.keys(ms).sya1) say1:function say1(){} => 可粗暴认为没有箭头表达式的都是普通函数
        console.log(this.a);
      },
      say2: function () {
        console.log(this.a);
      },
      say3: function () {
        console.log(this);
        return {
          ha: () => {
            console.log(this, '--------');
          }
        }
      }
    };
    ms.say(); // this是window (所处的外层作用域的 this 值)
    ms.say1(); // this是 ms 
    ms.say2();
    ms.say3.call({ x: 100 }).ha();


    // 构造函数
    class Mans {

      constructor() {
        this.name = 'Mans'
      }

      printName() {
        console.log(this.name);
      }

      printName1 = () => {  // ★ 不在原型上
        console.log(this.name);
      }

    }

    const MansCase = new Mans();
    MansCase.printName(); // Mans
    MansCase.printName1(); // Mans



    const otherObj = {
      name: 'otherObj',
      printName: MansCase.printName,
      printName1: MansCase.printName1
    }
    otherObj.printName(); // otherObj  this是otherObj
    otherObj.printName1(); // Mans   this是MansCase => 这个和上面的 obj1.hideObj.say() 调用者是hideObj


    /**********************************************************************
    特殊的setTimeout => 黑盒子,该API是浏览器内部提供,并非js部分中的
    
    chromium => 谷歌浏览器开源出来的一个东西(setTimeout代码的执行实现)
    fakeWin.setTimeout = function (fn, time) {
      fakeWin.setTimeout.called = true;
      fakeWin.setTimeout.that = this;
      if (typeof fn === "string") {
        eval(fn)
      } else {
        fn.apply(this, Array.prototype.slice.call(arguments, 2)) // this => window
      }
    };
    **************************************************************************/
    setTimeout(() => {
      console.log(this); // window 不管是否严格模式
    }, 100);

    var sets = {
      say: function () {

        // 箭头函数
        // setTimeout(() => {
        //   console.log(this); //  sets对象
        // }, 100);

        setTimeout(function () {
          console.log(this); //  window
        }, 100);
      }
    }

    sets.say();
  </script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值