前端面试-手写call/apply/bind

date
Oct 10, 2022
slug
write-call-apply-bind-function-by-yourself
status
Published
tags
Interview
summary
write the call, apply and bind function by yourself
type
Post

前言

常见前端面试题之手写call apply bind 函数
 

call 实现

分析:
  1. 判断当前调用mycall 的是否为一个函数类型,如果不是函数类型则直接抛出错误。
  1. 接收第一个参数为指定的this,不过这里需要对传入的参数判断,当它为null或者undefined时为window,其余则使用Object转化为对象处理。
  1. 在绑定的this 对象上赋值fn为当前的this,当前this即是外部调用的函数(this的隐式绑定)
  1. 调用当前函数并且传递剩余参数,将返回值赋值给result。
  1. 删除fn属性,最终将函数返回值一并返回。
 
代码实现:
Function.prototype.mycall = function(thisArg, ...restParameters){
    if(typeof this !== 'function'){
        throw TypeError('need function')
    }
    thisArg = (thisArg === undefined || thisArg === null) ? window : Object(thisArg) 
    thisArg.fn = this
    var = result = thisArg.fn(...restParameters);
    delete thisArg.fn;
    return result;
}
 
  • 这里判断是否为函数是参考网上做法,但是实际调试发现如果不是函数的话是无法调用mycall的,因此我个人觉得这个判断可以省略不写。

apply 实现

分析:
  1. apply 与call的实现大致逻辑差不多,只有参数部分需要额外处理一下。
  1. 由于apply第二个参数应该为数组,所以需要判断一下没有参数的情况,给定默认参数为空数组。
 
代码实现:
Function.prototype.myApply = function(thisArg, restParameters){
    thisArg = (thisArg === null || thisArg === undefined) ? window : Object(thisArg);
    thisArg.fn = this;
    var params = restParameters || [];
    var result;
    result = thisArg.fn(...params)
    delete thisArg.fn;
    return result;
}
 

bind 实现

分析:
  1. bind 与call 和apply的不同点在于它是返回一个函数,并且对于参数也需要额外处理
  1. 因为参数可能从bind 传入,也可能从返回的函数执行时传入,所以这里进行了一个参数合并操作。
 
代码实现:
Function.prototype.mybind = function(thisArg, ...bindArgs){
    thisArg = (thisArg === null || thisArg === undefined) ? window : Object(thisArg);
    thisArg.fn = this;
    function proxyFn(...newArgs){
        var params = [...bindArgs, ...newArgs]
        var result = thisArg.fn(...params);
        delete thisArg.fn;
        return result;
    }

    return proxyFn
}
 
 
 

© xk_wan 2021 - 2024