js 隐式绑定与隐式丢失

在学习函数this绑定时遇到一个很有意思的现象,请看下面代码

function fn(){
	console.log(this.a)
}
var a = "hello"
fn()

这段代码可能大家都知道执行结果是什么,就是控制台输出了hello
但是如果我在console.log(this.a)前面加上了"use strict"会发生什么?
结果是会报错
image
为什么呢?
因为在非严格模式下,上面代码的函数调用时应用了默认绑定,因此this指向全局对象
但是在严格模式下,不能将全局对象用于默认绑定,因此this就等于undefined
这就是js的默认绑定

接下来我们来讲讲隐式绑定,请看下面的代码

function fn(){
	console.log(this.a)
}
var a = "hello"
var obj = {
	a: "obj",
	fn: fn
}
obj.fn()

这段代码执行后,控制台会打印什么呢?
结果是控制台打印了obj
fn这个函数严格意义上讲并不属于obj对象
当函数被引用有上下文对象时,隐式绑定会把函数调用中的this绑定到这个上下文对象,此时的console.log(this.a)console.log(obj.a)是一样的,继续看下面的代码

function fn(){
	console.log(this.a)
}
var a = "hello"
var obj = {
	a: "obj",
	fn: fn
}
var objs = {
	a: "objs",
	obj : obj
}
objs.obj.fn() //obj

遇到这种情况,请记住:对象属性引用链中只有上层或者说最后一层在调用位置中起作用
this实际上是在函数被调用时发生的绑定,他指向什么完全取决于函数在哪里被调用

隐式丢失又是什么?
隐式丢失是被隐式绑定的函数丢失绑定对象,请看下面代码

function fn(){
	console.log(this.a)
}
var a = "hello"
var obj = {
	a: "obj",
	fn: fn
}
var demo = obj.fn; //函数别名
demo() //???

大家觉得这段代码最终控制台打印的是什么?
执行结果为,控制台打印了hello
为什么呢?
因为demo只是绑定了fn函数的引用,因此demo只是一个函数的调用,应用了默认绑定绑定到了全局对象,该情况很容易出现在回调函数上,例如:

function fn(){
	console.log(this.a)
}
var a = "hello"
var obj = {
	a: "obj",
	fn: fn
}
setTimeout(obj.fn,0); //hello

setTimeout第一个参数是传入回调函数,obj.fn被当做一个函数进行绑定,可以理解为:

function setTimeout(fn,delay){
	//等待delay毫秒后执行
	fn() //obj.fn
}

这就是js的隐式丢失现象
大家在写代码的时候,请注意这种现象,避免采坑…
如有问题,请在下方留言

《你不知道的JavaScript》学习记录系列
其他笔记请查看专栏:
《你不知道的JavaScript》学习笔记

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值