事例一 : 对于赋值的自执行函数,他都指向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();
事例三:
- 箭头函数,不管是call, apply, bind他都不能改变this的指向。都是在定义的时候确定的。
- 注意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
注: 此上例题都是总结自网络,只作个人总结。