前段时间刷掘金,看到一片文章:《js基础-面试官想知道你有多理解call,apply,bind》
发现自己经常记混淆这几种方法的用法,读完文章后自己做个简单的总结
call、apply、bind都是函数原型上的方法,所以只有函数才能调用他们,否则会出错
const fun = function () {
return 1;
};
const str = '';
const obj = {};
console.log('fun.call=', fun.call(null)); // 输出: 1
console.log('str.call=', str.call(null)); // Uncaught TypeError: str.call is not a function
console.log('obj.call=', obj.call(null)); // Uncaught TypeError: str.call is not a function
作用:
改变函数运行时的this指向
用法:
fun.call(thisObj, params1, params2, params2, ...)
fun.apply(thisObj, [params1, params2, params2, ...])
fun.bind(thisObj, params1, params2, params2, ...)
call/apply与bind的区别
参数:
==thisObj==:
- fun的this要指向的地方
- 非严格模式下:thisArg为空或者指定为null,undefined,fun中的this指向window对象.
const fun = function () {
console.log(this); // 输出的this都是 window
};
console.log('call ===>')
fun.call(undefined) // fun.call() fun.call(null)
console.log('apply ===>')
fun.apply(undefined) // fun.apply() fun.apply(null)
console.log('bind ===>')
fun.bind(undefined)() // fun.bind() fun.bind(null)
- 严格模式下:thisArg为空或者指定为undefined时fun的this为undefined;当thisArg为null时,输出null
const fun = function () {
"use strict";
console.log(this); // undefined or null
};
console.log('call ===>')
fun.call(undefined) // fun.call() fun.call(null)
console.log('apply ===>')
fun.apply(undefined) // fun.apply() fun.apply(null)
console.log('bind ===>')
fun.bind(undefined)() // fun.bind() fun.bind(null)
- 值为原始值(数字,字符串,布尔值)的this会指向该原始值的自动包装对象,如 String、Number、Boolean
const fun = function () {
console.log(this);
};
console.log('call ===>');
fun.call(12); // =>this输出为: Number {12}
fun.call('abc'); // =>this输出为: String {"abc"}
fun.call(false); // =>this输出为: Boolean {false}
console.log('apply ===>');
fun.apply(12);// =>this输出为: Number {12}
fun.apply('abc');// =>this输出为: String {"abc"}
fun.apply(false);// =>this输出为: Boolean {false}
console.log('bind ===>');
fun.bind(12)();// =>this输出为: Number {12}
fun.bind('abc')();// =>this输出为:String {"abc"}
fun.bind(false)();// =>this输出为: Boolean {false}
==params==:
- 非必需。传给fun的参数
- apply接收的是一个数组,call/bind是单个参数传入
执行:
call/apply改变了函数的this上下文后,马上执行该函数
bind则是返回改变了上下文后的函数,不执行该函数
返回值:
call/apply 返回fun的执行结果
bind返回fun的拷贝,并指定了fun的this指向,保存了fun的参数。
使用:
- 参数数量/顺序确定就用call,参数数量/顺序不确定的话就用apply。
- 考虑可读性:参数数量不多就用call,参数数量比较多的话,把参数整合成数组,使用apply。
- 参数集合已经是一个数组的情况,用apply,比如上文的获取数组最大值/最小值。