关于this的一些例题

234 阅读3分钟

事例一 : 对于赋值的自执行函数,他都指向window,不管是对外部函数的引用还是对一个对象中属性函数的引用。

  
    function foo() {
      console.log(this);
    }

    var obj1 = {
      name: "obj1",
      foo: foo
    };

    var obj2 = {
      name: "obj2"
    }

    obj1.foo(); // obj1对象
    (obj2.foo = obj1.foo)();  // window
   
    var obj1 = {
      name: "obj1",
      foo() {
        console.log(this)
      }
    };

    var obj2 = {
      name: "obj2"
    };

    (obj2.bar = obj1.foo)();// 也是window

    (obj2.bar)()// obj2

事例二:对于没有赋值的自执行函数,还是谁调用它,它指向谁。

    var name = "window";
    var person = {
      name: "person",
      sayName: function () {
        console.log(this.name);
      }
    };
    function sayName() {
      var sss = person.sayName;
      sss(); //window
      person.sayName(); //person
      (person.sayName)(); //person,这里是自己的对象中的函数,并不是外部函数的引用
      (b = person.sayName)(); //window
    }
    sayName();

事例三:

  1. 箭头函数,不管是call, apply, bind他都不能改变this的指向。都是在定义的时候确定的。
  2. 注意this指向的是外层函数的环境。
    var name = 'window'
    var person1 = {
      name: 'person1',
      foo1: function () {
        console.log(this.name)
      },
      foo2: () => console.log(this.name),
      foo3: function () {
        return function () {
          console.log(this.name)
        }
      },
      foo4: function () {
        return () => {
          console.log(this.name)
        }
      }
    }

    var person2 = { name: 'person2' }
    // 隐式绑定,肯定是person1
    person1.foo1(); // person1
    // 隐式绑定和显示绑定的结合,显示绑定生效,所以是person2
    person1.foo1.call(person2); // person2

    // foo2()是一个箭头函数,不适用所有的规则
    person1.foo2() // window
    // foo2依然是箭头函数,不适用于显示绑定的规则
    person1.foo2.call(person2) // window

    // 获取到foo3,但是调用位置是全局作用于下,所以是默认绑定window
    person1.foo3()() // window
    // foo3显示绑定到person2中
    // 但是拿到的返回函数依然是在全局下调用,所以依然是window
    person1.foo3.call(person2)() // window
    // 拿到foo3返回的函数,通过显示绑定到person2中,所以是person2
    person1.foo3().call(person2) // person2

    // foo4()的函数返回的是一个箭头函数
    // 箭头函数的执行找上层作用域,是person1
    person1.foo4()() // person1
    // foo4()显示绑定到person2中,并且返回一个箭头函数
    // 箭头函数找上层作用域,是person2
    person1.foo4.call(person2)() // person2
    // foo4返回的是箭头函数,箭头函数只看上层作用域
    person1.foo4().call(person2) // person1

事例四:虽然箭头函数中的this是在定义时被确定的。但是外层的函数为非箭头函数,他可以在运行时改变,所以内部接头函数的this间接被改变。


    var name = 'window'
    function Person(name) {
      this.name = name
      this.obj = {
        name: 'obj',
        foo1: function () {
          return function () {
            console.log(this.name)
          }
        },
        foo2: function () {
          return () => {
            console.log(this.name)
          }
        }
      }
    }
    var person1 = new Person('person1')
    var person2 = new Person('person2')

    // obj.foo1()返回一个函数
    // 这个函数在全局作用于下直接执行(默认绑定)
    person1.obj.foo1()() // window
    // 最终还是拿到一个返回的函数(虽然多了一步call的绑定)
    // 这个函数在全局作用于下直接执行(默认绑定)
    person1.obj.foo1.call(person2)() // window
    person1.obj.foo1().call(person2) // person2

    // 拿到foo2()的返回值,是一个箭头函数
    // 箭头函数在执行时找上层作用域下的this,就是obj
    person1.obj.foo2()() // obj
    // foo2()的返回值,依然是箭头函数,但是在执行foo2时绑定了person2
    // 箭头函数在执行时找上层作用域下的this,找到的是person2
    person1.obj.foo2.call(person2)() // person2
    // foo2()的返回值,依然是箭头函数
    // 箭头函数通过call调用是不会绑定this,所以找上层作用域下的this是obj
    person1.obj.foo2().call(person2) // obj

注: 此上例题都是总结自网络,只作个人总结。