了解一下 this

this

由于 JavaScript 的设计原理:在函数中,可以引用运行环境中的变量。因此就需要一个机制来让我们可以在函数体内部获取当前的运行环境,这就是 this
因此要明白 this 指向,其实就是要搞清楚函数的运行环境,说白了就是,谁调用了函数。

不同情况的调用,this 指向也是不同的。我们先来看几个函数调用的场景:

function foo () {
	console.log(this, this.?a);
}
let a = 1;
foo(); // Window{} 	1

let obj = {
	a: 2,
	foo
}
obj.foo(); // {a: 2, foo: ƒ}	2

let c = new foo(); // foo {}   undefined
  • 直接调用 foo,就相当于 window.foo()this => Window
  • 对于 obj.foo() 来说,你只要记住,谁调用了 foo,谁就是 this,所以 this => obj
  • 对于 new 方式调用,this 永远指向 c,不会被任何方式改变 this

了解了以上几种情况之后, 其实大多数代码中的 this 就没啥问题了,下面我们来看箭头函数中的 this

function fn() {
	return () => {
		return () => {
			console.log(this)
		}
	}
}
console.log(fn()()()) // Window{}
  • 首先箭头函数其实是没有 this 的,它里面的 this 只取决于包裹箭头函数的第一个普通函数的 this
  • 在这个例子中,第一个普通函数为 fn,所以此时的 thisWindow
  • 另外对箭头函数使用 bind 这类函数也是无效的。

最后一种情况就是 bind 这些改变上下文的 API 了,对于这些函数来说,this 取决于第一个参数,如果第一个参数为空,那么就为 Window
说到 bind,如果对一个函数进行多次 bind,会怎么样呢?

let fish = { cat: 1 }
let fn = function () {
    return console.log(this)
}
fn.bind().bind(fish)()

如果你认为输出结果是 fish 那就错了,我们可以换成另一种形式:

let fn2 = function fn1() {
    return function () {
        return fn.apply()
    }.apply(fish)
}
fn2()

由此可以看出,不管我们给函数 bind 多少次,fn 中的 this 永远都是有第一个 bind 决定的,所以最后的结果是 Window

let fish = { cat: 1 }
let fn = function () {
    return console.log(this.cat)
}
fn.bind(fish)() // 1

以上就是 this 的规则了,但是可能会出现多个规则同时存在的情况,这时候不同的规则之间会根据优先级来决定 this 的最终指向哪里。

首先,new 的方式优先级最高,其次是 bind 这些函数,然后是 obj.foo() 这种调用方式,最后是 foo 这种调用方式。
同时,箭头函数的 this 一旦被绑定,就不会再被任何方式所改变。
在这里插入图片描述
但是,光是以上简单的几种机制并不能满足我们的日常需求,因此提供了三种方式来手动改变 this 指向:

func.bind(target, param1, param2, ...)
func.call(target, param1, param2, ...)
func.apply(target, [param1, param2, ...])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值