fe-interview icon indicating copy to clipboard operation
fe-interview copied to clipboard

说一下对bind,call,apply三个函数的认识,自己实现一下bind方法

Open FunnyZ opened this issue 5 years ago • 3 comments

说一下对bind,call,apply三个函数的认识,自己实现一下bind方法

FunnyZ avatar Jul 16 '19 02:07 FunnyZ

粗略讲一下,希望大佬们能补充下。

首先这三个方法都是用来改变函数的 this 的绑定(指向)的。 它们的用法如下:

func.apply(thisArg, [argsArray])

fun.call(thisArg, arg1, arg2, ...)

function.bind(thisArg[, arg1[, arg2[, ...]]])

区别:

  • call 和 apply 的区别在于传参的形式不一样,apply 的参数形式是数组或类数组对象,call 的参数形式则是一个个排列的参数值;

  • bind 返回的是原函数的拷贝,并拥有指定的 this 值和初始参数;而 call 和 apply 都是直接返回原函数的返回值,或 undefined;即 bind 是需要手动去调用的,而 apply 和 call 都是立即自动执行。

实现 bind 方法可以参考 MDN bind polyfill

或者

const bind = (fn, context, ...boundArgs) => (...args) => fn.apply(context, [...boundArgs, ...args]);

FunnyZ avatar Jul 17 '19 05:07 FunnyZ

有一个疑惑: var obj=[2,3,7,3,8,1]; Math.max.apply(null,obj);//output 8 Math.max(obj);//output NaN 为何使用了apply后,第二个参数却有了展开语法的效果?难道使用apply后参数会被展开? 我能理解Math.max(...obj),但是apply明明传入的是数组,和Math.max要求的参数不一致呀

hulkyuan avatar Oct 12 '19 07:10 hulkyuan

模拟Math.max()

function max() {
    let max = arguments[0];
    for(let i = 0; i < arguments.length; i++) {
        if(max < arguments[i]) {
            max = arguments[i];
        }
    }
    return max;
}

max(...obj) // 8 max.call(null, ...obj); // 8 max.apply(null,obj) // 8 apply内部实现也有参数展开这一步

@hulkyuan

artdong avatar Jul 09 '20 03:07 artdong