JS中this指向问题
默认绑定
-
全局环境下的this指向了window
-
<script> console.log(this) </script>
-
-
函数独立调用,函数内部的this也指向了window
-
<script> function fn() { console.log(this) } fn() </script>
-
-
被嵌套的函数独立调用时,this默认指向了window
-
<script> let a = 0 const obj = { a: 2, foo: function () { //函数当做对象的方法来调用 this指向了obj let that = this function test() { console.log(that.a) console.log(this.a) } test() }, } obj.foo() </script>
-
-
IIFE 立即执行函数中内部的this指向了window
-
<script> (function () { console.log(this) })() </script>
-
-
闭包中this默认指向了window
-
<script> let a = 0 const obj = { a: 2, foo: function () { let _this = this return function test() { console.log('闭包中的this指向', this) return _this.a } } } let fn = obj.foo() console.log(fn()) </script>
-
隐式绑定
-
函数当作方法来调用,this指向了直接对象
-
<script> function foo() { console.log(this.a) } const obj = { a: 1, foo: foo, obj2: { a: 2, foo: foo } } // foo()函数的直接对象是obj,this的指向指向了obj obj.foo() // foo()函数的直接对象是obj2,this的指向指向了obj2 obj.obj2.foo() </script>
-
隐式丢失
-
指被隐式绑定的函数丢失了绑定对象 从而默认绑定到window
-
函数别名
-
<script> var a = 0 function foo() { console.log(this.a) } const obj = { a: 1, foo: foo } obj.foo() // 把obj.foo赋值给别名bar,造成隐式丢失的情况.因为只是把obj.foo赋值了bar变量.而bar与obj对象毫无关系 let bar = obj.foo bar() </script>
-
-
参数传递
-
<script> var a = 0 function foo() { console.log(this.a) } function bar(fn) { fn() } const obj = { a: 1, foo: foo } // 把obj.foo当做参数传递到bar函数中,有隐式的函数赋值 fn = obj.foo,只是把foo函数赋值给了fn,而fn与obj对象毫无关系,所以当前foo函数内部的this指向了window bar(obj.foo) </script>
-
-
内置函数 setTimeout()和setInterval()第一个参数的回调函数中的this默认指向了window
-
<script> var a = 10 function foo() { console.log(this.a) } const obj = { a: 1, foo: foo } setTimeout(obj.foo, 1000) </script>
-
-
间接调用
-
<script> function foo() { console.log(this.a) } var a = 2 const obj = { a: 3, foo: foo } const p = { a: 4 } // 隐式绑定,函数当做对象中的方法来使用,内部的this指向了该对象 obj.foo()//3 // 将obj.foo函数对象赋值给p.foo函数,然后立即执行。相当于仅仅是foo()函数的立即调用,内部的this默认指向了window (p.foo = obj.foo)()//2 // 将obj.foo赋值给p.foo函数,之后p.foo()函数再执行,其实是属于p对象的方法的指向,this指向了当前的p对象 p.foo = obj.foo p.foo()//4 </script>
-
显示绑定
-
call(),apply(),bind()把对象绑定到this上
-
<script> var a = 0 function foo() { console.log(this.a) } const obj = { a: 2 } foo()//0 foo.call(obj)//2 foo.apply(obj)//2 let fn = foo.bind(obj) fn()//2 </script>
-
-
硬绑定是显示绑定的一个变种,使得this不能再被改变
-
<script> var a = 0 function foo() { console.log(this.a) } const obj = { a: 2 } let bar = function () { foo.call(obj) } bar()//2 setTimeout(bar, 2000)//2 bar.call(window)//2 </script>
-
-
数组的forEach(fn,对象) map() filter() some() every()
-
<script> var id = 'window' const obj = { id: 'fn' } const arr = [1, 2, 3] arr.forEach(function (el, index) { console.log(el, index, this) }, obj) </script>
-
new绑定
-
new关键来执行函数,相当于构造函数来实例化对象,那么内部的this指向了当前实例化的对象
-
<script> function fn(name, age) { this.name = name this.age = age // 如果是new关键来执行函数 相当于构造函数来实例化对象,那么内部的this指向了当前实例化的对象 console.log(this) return } const fnn = new fn('ds', 12) console.log(fnn) </script>
-
严格模式下this指向
-
严格模式下,独立调用的函数内部的this指向了undefined
-
<script> function fn() { 'use strict' console.log(this) } fn() </script>
-
-
严格模式下,函数apply()和call()内部的this始终是它们的第一个参数
-
<script> var color = 'red' function showColor() { 'use strict' console.log(this) console.log(this.color) } showColor.call(undefined) </script>
-