call/apply/bind这三个都是用来改变函数执行时this的指向的,我们看看call方法的使用和原理(js重构的call方法和原生的call方法不完全一样),来聊一聊这三个函数之间的区别。
call() 方法
语法:函数.call([context], [params])
参数解析
context:被改变之后的this
params:函数执行所传参数
举例
window.name = "WINDOW";
var obj= {
name: "OBJ"
}
function Fnn() {
console.log(this.name)
}
Fnn.call(obj); //=>OBJ
Fnn.call(); //WINDOW
Fnn(); //WINDOW
重构call方法
思路:
*1、把当前this指向的方法变成被改变this的一个属性
*2、执行函数
*3、删除被改变后this上的函数
*4、把重构的call方法赋值到函数原型上
以举例中Fnn.call(obj)为例,把Fnn函数变成obj对象里的属性Fnn,执行Fnn时,相当于obj.Fnn(),this当然指向的是obj。
~function() {
// call方法
function call(context) {
context = context || window;
let args=[], result;
for(let i=1;i<arguments.length;i++){
args.push(arguments[i])
}
//this: fn
context.$fn = this;
//fn执行
result = context.$fn(...args);
delete context.$fn;
// 返回执行结果
return result;
}
//扩展call方法到FUNCTION原型上
Function.prototype.call = call;
}();
重写方法测试
执行重构的方法后,myCall方法已经挂载到Function原型上
借助举例中的代码,测试myCall方法
call、apply、bind之间的区别
call、apply和bind用法大同小异,我们来看看他们的区别:
1)、bind会产生新的函数,(把对象和函数绑定死后,产生新的函数)
2)、call和apply不会产生新的函数,只是在调用时,绑定一下而已。
3)、call和apply的区别,第一个参数都是要绑定的this,apply第二个参数是数组(是函数的所有参数),call把apply的第二个参数单列出来。