call、apply、bind 方法详解

一、call、apply、bind 的共同点

  • 改变函数的 this 指向
  • 第一个参数都是 this 要指向的对象

 二、call、apply、bind 的区别

  • call、apply 都是立即执行,bind 不会立即执行,因为 bind 的返回值是一个函数
  • apply 第二个参数是数组,call、bind 有多个参数时要依次传参,会一一对应

应用场景 

call:实现继承

apply:与数组相关,比如:Math.max

bind:改变 this, 必须调用函数

<script>
    let obj = {
        str: '我是张三'
    }
    function fun(name, age) {
        this.name = name
        this.age = age
        // console.log(this.str);
        console.log(this);
    }
    // fun() // undefined; 因为 this 指向 window, 且 window 不存在属性 str

    // 调用
    // fun.call(obj) // 立即执行: 我是张三
    // fun.apply(obj) // 立即执行: 我是张三
    // fun.bind(obj) // 没有输出, 因为 bind 返回值是一个函数
    // console.log(fun.bind(obj));
    /*
        ƒ fun() {
            console.log(this.str);
        }
    */
    // fun.bind(obj)() // 我是张三

    // 传参
    fun.call(obj, 'zero', 15) // {str: '我是张三', name: 'zero', age: 15}
    fun.apply(obj, ['tom', 18]) // {str: '我是张三', name: 'tom', age: 18}
    fun.bind(obj, 'john', 20)() // {str: '我是张三', name: 'john', age: 20}
    fun.bind(obj)('john', 20) // {str: '我是张三', name: 'john', age: 20}

</script>

三、原生实现 call、apply、bind

<script>
    // call()
    Function.prototype.myCall = function () {
        // 判断调用对象是否为函数
        if (typeof this !== 'function') {
            console.error("type error");
        }
        // 第一个参数, 非严格模式下,null 或 undefined 会转向 window
        let target = arguments[0] || window
        // 获取剩余参数
        let arg = Array.from(arguments).splice(1)
        target.fn = this
        let result = target.fn(...arg)
        delete target.fn
        return result
    }
</script>
<script>
    // apply
    Function.prototype.myApply = function () {
        // 判断调用对象是否为函数
        if (typeof this !== 'function') {
            console.error("type error");
        }
        // 第一个参数, 非严格模式下,null 或 undefined 会转向 window
        let target = arguments[0] || window
        // 获取参数
        let arg = arguments[1]
        target.fn = this
        let result = target.fn(...arg);
        delete target.fn
        return target
    }
</script>
<script>
    // bind
    Function.prototype.myBind = function () {
        // 判断调用对象是否为函数
        if (typeof this !== 'function') {
            console.error("type error");
        }
        // 第一个参数, 非严格模式下,null 或 undefined 会转向 window
        let target = arguments[0] || window
        // 获取参数
        let arg = Array.from(arguments).splice(1)
        target.fn = this
        return function () {
            target.fn(...arg)
            delete target.fn
        }
    }
</script>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值