call、apply和bind

2019-05-06  本文已影响0人  locky丶

有时我们需要借用某个对象的方法赋予另一个对象,此时就需要用到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
上一篇下一篇

猜你喜欢

热点阅读