JavaScript自我实现系列:call,apply,bind

Posted best-xiaoqiang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript自我实现系列:call,apply,bind相关的知识,希望对你有一定的参考价值。

call, apply, bind

call

使用:

// 1. 定义一个女孩叫x
var x = {
    // 她的身高是170
    height: 170,
    // 她有一双高跟鞋,作用是让她长高10厘米
    highShoes: function(){
        this.height += 10
    }
}
// x穿上高跟鞋
x.highShoes()
// 于是身高变成了180
console.log(x.height) // 180

// 2. 定义一个帅哥叫q
var q = {
    // 他的身高是160,...
    height: 160
}
// q也想增高一下
// q.highShoes() // 但是报错了:Uncaught TypeError: q.highShoes is not a function
// 因为q没有高跟鞋

// 3. q借用x的高跟鞋
x.highShoes.call(q)
// 我也长高啦!
console.log(q.height) // 170

// 这里的this就是指高跟鞋的拥有者,即x女孩
// 如果不通过call改变this的指向,这个高跟鞋的拥有者永远是x
// q通过call借来了x的高跟鞋

所以,call的作用就是:

高跟鞋搬运工

改变this的指向

apply, bind的作用同上。

apply, bind

和call的区别:


// 定义一个主人翁
var x = {}

// 定义一个化妆函数
function makeUp(color, style) {
    // 涂什么颜色的口红
    this.lips = color
    // 留什么样式的发型
    this.hair = style
}

// 用call:
makeUp.call(x, ‘red‘, ‘longHair‘)

// 用apply:
makeUp.apply(x, [‘red‘, ‘longHair‘])

// 用bind:
makeUp.bind(x, ‘red‘, ‘longHair‘)()

第一个参数为null时:

makeUp.call(null, ‘yellow‘, ‘shortHair‘)
// 非严格模式下,第一个参数是null,this指向的window
console.log(window.lips, window.hair) // "yellow", "shortHair"

自我实现

实现一个call函数:

/*
*  call的工作原理就是
*  将一个函数的this指向某个上下文,从而使这个上下文可以调用这个函数。
*  
*  函数就像某个工具,
*  call要完成的就是一个借用的过程。
*  
*  一曲《借我》送给大家。
*/ 

Function.prototype.lendMe = function (borrower) {
    // 1. 谁借?默认是window借。
    var borrower = borrower || window
    // 2. 借啥?哪个函数调用的lendMe,lendMe的this就是这个函数。
    // 当把这个函数赋值给borrower的方法时,就已经借到了。
    borrower.tool = this
    // 获得传给函数的参数
    var args = [...arguments].slice(1)
    // 3. 借用。前面是借,现在是用。
    var result = borrower.tool(...args)
    // 4. 出来借总是要还的。
    delete borrower.tool
    // 5. 用完的东西给你。
    return result
}

apply和call几乎一样:

Function.prototype.myApply = function (borrower) {
    var borrower = borrower || window
    borrower.tool = this
    // 第二个参数是一个数组
    var arg = arguments[1] || []
    var result = borrower.tool(...arg)
    delete borrower.tool
    return result
}

实现一个bind函数:

/*
*  这里对bind函数的实现,
*  就是利用闭包,返回了一个准备通过apply的方式执行的函数。
*/
Function.prototype.myBind = function (borrower) {
    if(typeof this !== ‘function‘){
        throw new TypeError(‘Error‘)
    }
    var tool = this
    var args = [...arguments].slice(1)
    return function() {
        return tool.apply(borrower, args.concat(...arguments))
    }
}

javascript自我实现系列 点击查看

以上是关于JavaScript自我实现系列:call,apply,bind的主要内容,如果未能解决你的问题,请参考以下文章

学习Javascript之模拟实现bind

手写系列 # 3:实现 call 方法

深度剖析 javascript call方法实现继承的原理

Javascript之模拟实现call,apply

原生实现JavaScript的call()apply()bind()

javascript 中的继承实现, call,apply,prototype,构造函数