有时我们需要借用某个对象的方法赋予另一个对象,此时就需要用到call、apply和bind。
本质上这三个方法都是通过改变this的指向来实现功能,所以我们经常将它们三个放在一起。但是要再分的细些,就要把call和apply放一起,而bind会单独讲。
call 、apply
有些方法在对象“出身”时就自带了,我在此将其称为天赋。这些方法可以直接被使用,无需call、apply。
var arr = [1, 2, 3]
var b = arr.concat([5, 6, 7])
// var b = Array.prototype.concat.call(arr, [5, 6, 7]) // 用call也能实现
console.log(b) // [1,2,3,5,6,7]
我们可以借用Array的concat方法,将两个数组连接起来,因为[1,2,3]自己有concat方法,所以在这里可以直接使用,无需call借给arr了。
何时能用上呢,请看下面这段代码:
var c = {value:5}
// c是对象,它没有concat方法
// 运行时会报错 c.concat is not a function
var d = c.concat(7)
为了让 c 也有concat的能力,我们就要call(打电话)给Array进行求助。“喂,Array,你在么?有个事要请你帮下忙,把你的concat借我用一下,用完还你。”
var c = {value:5}
var d = Array.prototype.concat.call(c, 7,8)
console.log(d) // [ { value: 5 }, 7 ,8]
call和apply的功能除了参数的类型不同外,其他都是一样的。
var c = {value:5}
// call 的参数以逗号分隔, apply的参数是个数组
var d = Array.prototype.concat.apply(c,[7,8])
console.log(d) // [ { value: 5 }, 7 ,8]
bind
要理解bind需要先熟悉this的用法,this是根据上下文来指向不同的对象。
let cat = {
sound: 'miao',
talk: function () {
return this // 此时的this 指向cat
}
}
console.log(cat.talk().sound) // miao
我希望this指向talk,这时候 bind 就出场了。
let cat = {
sound: 'miao',
talk: function () {
return this.sound
}
}
let unbindGetTalk = cat.talk;
console.log(unbindGetTalk()) // undefined
// bind把unbindGetTalk内的this指向了cat,
// 让unbindGetTalk内的this.sound 指向了sound:'miao'这个属性。
let bindGetTalk = unbindGetTalk.bind(cat)
console.log(bindGetTalk()) // miao
网友评论