加载中...
PAGE

js 隐式绑定与隐式丢失

Post on 2021-10-28 12 0

在学习函数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》学习笔记

mysql 树目录查询语句优化,提高查询效率

mysql 树目录查询语句优化,提高查询效率

阅读更多
js 10分钟学会隐式转换

js 10分钟学会隐式转换

阅读更多
微信小程序地图组件 无限闪烁导致小程序崩溃

微信小程序地图组件 无限闪烁导致小程序崩溃

阅读更多

暂无评论

    发表评论
    返回顶部
    X