今天又是连续暴雨的一天,已连续下雨好几周了。房间里黑漆漆的,突然想到JavaScript 的call()、apply()、bind()
三个函数。。。人家都在想女友,而我此时此刻想到了代码,太惨了。。。一脸懵逼,还忘记了它们的区别,果然雨下得连脑子都不好使了。。。
- 马上在浏览器写了一段代码验证一下三个函数有啥不同,如下:
let bigBaby = {
name: '大宝',
age: 81,
ageFun: () => {
console.log(this.name + "年龄:" + this.age)
},
descFun: (height , weight, hobby) => {
console.log(this.name + "年龄:" + this.age + " 身高:" + height + "米 体重:" + weight + " 爱好:" + hobby)
}
}
let littleBaby = {
name: '小宝',
age: 18
}
bigBaby.ageFun.call(littleBaby) // undefined年龄:undefined
bigBaby.ageFun.apply(littleBaby) // undefined年龄:undefined
bigBaby.ageFun.bind(littleBaby)() // undefined年龄:undefined
- 看到结果后,才晃过来
bigBaby
对象里的箭头函数作用域提升了,this指向window,所以取不到值undefined了。。。粗心容易犯错,别想着一写函数就写箭头函数。。。紧接着改成如下代码:
let bigBaby = {
name: '大宝',
age: 81,
ageFun: function () {
console.log(this.name + "年龄:" + this.age)
},
descFun: function (height , weight, hobby) {
console.log(this.name + "年龄:" + this.age + " 身高:" + height + "米 体重:" + weight + " 爱好:" + hobby)
}
}
let littleBaby = {
name: '小宝',
age: 18
}
bigBaby.ageFun.call(littleBaby) // 小宝年龄:18
bigBaby.ageFun.apply(littleBaby) // 小宝年龄:18
bigBaby.ageFun.bind(littleBaby)() // 小宝年龄:18
- 看到如下结果,就对了。第一点:
call()、apply()、bind() 三个函数都是用来重定义
this
这个对象的,把原本 bigBaby 的方法重定义为 littleBaby 的方法,所以读取到的 age 是
littleBaby 定义的 18 岁
call、apply直接执行函数
,bind 返回的是一个新的函数
,所以要调用它才会被执行
- 接着测试,代码如下:
let bigBaby = {
name: '大宝',
age: 81,
ageFun: function () {
console.log(this.name + "年龄:" + this.age)
},
descFun: function (height, weight, hobby) {
console.log(this.name + "年龄:" + this.age + " 身高:" + height + "米 体重:" + weight + " 爱好:" + hobby)
}
}
let littleBaby = {
name: '小宝',
age: 18
}
bigBaby.descFun.call(littleBaby, 2, '200斤', (() => '篮球')()) // 小宝年龄:18 身高:2米 体重:200斤 爱好:篮球
bigBaby.descFun.apply(littleBaby, [2, '200斤', (() => '篮球')()]) // 小宝年龄:18 身高:2米 体重:200斤 爱好:篮球
bigBaby.descFun.bind(littleBaby, 2, '200斤', (() => '篮球')())() // 小宝年龄:18 身高:2米 体重:200斤 爱好:篮球
- 看到如下结果,第二点:
除了第一个参数,后面的参数都是函数的入参
call 的参数是直接放进去的,全都用逗号分隔,直接放到后面bigBaby.descFun.call(littleBaby, 2, '200斤', (() => '篮球')())
apply 的所有参数都必须放在一个数组里面传进去bigBaby.descFun.apply(littleBaby, [2, '200斤', (() => '篮球')()])
bind 的参数是直接放进去的,全都用逗号分隔,直接放到后面,和 call 一样bigBaby.descFun.bind(littleBaby, 2, '200斤', (() => '篮球')())()
三者的参数允许是各种类型
- 总结
call()、apply()、bind() 三个函数都是用来重定义
this
这个对象的call 和 bind 的函数入参参数都用逗号分隔传入函数中,apply 的函数入参参数要放在一个数组里面传入函数中