Skip to content
本页目录

call apply bind

区别

call

js
fn.call(null, params); // 参数列表
fn.call(null, params); // 参数列表

当第一参数为 nullundefined 时,默认指向 window 对象;

apply

js
fn.call(null, array); // 数组
fn.call(null, array); // 数组

当第一参数为 nullundefined 时,默认指向 window 对象;

bind

js
fn.bind(null, params)(); // 参数列表
fn.bind(null, params)(); // 参数列表

当第一参数为 nullundefined 时,默认指向 window 对象; 返回值为改变了 this 的函数

源码实现

call

JS
Function.prototype._call = function(obj) {
    var obj = obj || window;
    obj.p = this;
    var newArguments = [];

    for(var i = 1; i < arguments.length; i++) {
        newArguments.push('arguments[' + i + ']');
    }
    var result = eval('obj.p(' + newArguments + ')');
    delete obj.p;
    return result;
}

// 展开运算符实现简易版
Function.prototype._call = function (obj, ...args) {
    const newObj = obj || globalThis;
    newObj.p = this;
    const result = newObj.p(...args);
    delete newObj.p;
    return result;
};
Function.prototype._call = function(obj) {
    var obj = obj || window;
    obj.p = this;
    var newArguments = [];

    for(var i = 1; i < arguments.length; i++) {
        newArguments.push('arguments[' + i + ']');
    }
    var result = eval('obj.p(' + newArguments + ')');
    delete obj.p;
    return result;
}

// 展开运算符实现简易版
Function.prototype._call = function (obj, ...args) {
    const newObj = obj || globalThis;
    newObj.p = this;
    const result = newObj.p(...args);
    delete newObj.p;
    return result;
};

apply

JS
Function.prototype._apply = function(obj, arr) {
    var obj = obj || window;
    var result;

    obj.p = this;

    if(!arr) {
        result = obj.p();
    } else {
        var newArguments = [];
        for(var i = 1; i < arguments.length; i++) {
        newArguments.push('arguments[' + i + ']');
        result = eval('obj.p(' + newArguments + ')');
    }

    delete obj.p;
    return result;
}
Function.prototype._apply = function(obj, arr) {
    var obj = obj || window;
    var result;

    obj.p = this;

    if(!arr) {
        result = obj.p();
    } else {
        var newArguments = [];
        for(var i = 1; i < arguments.length; i++) {
        newArguments.push('arguments[' + i + ']');
        result = eval('obj.p(' + newArguments + ')');
    }

    delete obj.p;
    return result;
}

bind

JS
Function.prototype._bind = function (obj) {

    var _this = this;
    // 获取
    var arr = Array.prototype.slice.call(arguments, 1);

    var Fn = function() {
        // 将所有参数转为数组
        var arr2 = Array.prototype.slice.call(arguments);
        var arrSum = arr.concat(arr2);
        if(this instanceof Fn) {
            _this.apply(this, arrSum);
        } else {
            _this.apply(obj, arrSum);
        }
    }
    Fn.prototype = _this.prototype;

    return Fn;
}


Function.prototype._bind = function (obj) {
    // 判断调用对象是否为函数
    if (typeof this !== "function") {
        throw new TypeError("Error");
    }

    // 获取参数
    const args = [...arguments].slice(1),
          fn = this;

    return function Fn() {

        // 根据调用方式,传入不同绑定值
        return fn.apply(this instanceof Fn ? new fn(...arguments) : context, args.concat(...arguments)); 
    }
}
Function.prototype._bind = function (obj) {

    var _this = this;
    // 获取
    var arr = Array.prototype.slice.call(arguments, 1);

    var Fn = function() {
        // 将所有参数转为数组
        var arr2 = Array.prototype.slice.call(arguments);
        var arrSum = arr.concat(arr2);
        if(this instanceof Fn) {
            _this.apply(this, arrSum);
        } else {
            _this.apply(obj, arrSum);
        }
    }
    Fn.prototype = _this.prototype;

    return Fn;
}


Function.prototype._bind = function (obj) {
    // 判断调用对象是否为函数
    if (typeof this !== "function") {
        throw new TypeError("Error");
    }

    // 获取参数
    const args = [...arguments].slice(1),
          fn = this;

    return function Fn() {

        // 根据调用方式,传入不同绑定值
        return fn.apply(this instanceof Fn ? new fn(...arguments) : context, args.concat(...arguments)); 
    }
}