在学习函数this绑定时遇到一个很有意思的现象,请看下面代码
function fn(){
console.log(this.a)
}
var a = "hello"
fn()
这段代码可能大家都知道执行结果是什么,就是控制台输出了hello
但是如果我在console.log(this.a)
前面加上了"use strict"
会发生什么?
结果是会报错
为什么呢?
因为在非严格模式
下,上面代码的函数调用时应用了默认绑定
,因此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》学习笔记