fe-interview
fe-interview copied to clipboard
说一下对bind,call,apply三个函数的认识,自己实现一下bind方法
说一下对bind,call,apply三个函数的认识,自己实现一下bind方法
粗略讲一下,希望大佬们能补充下。
首先这三个方法都是用来改变函数的 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]);
有一个疑惑:
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要求的参数不一致呀
模拟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