call,apply,bind区别:
1.三者都能改变函数this指向问题;
2.apply,bind主动调用,bind返回的是改变this指向后的新函数;
3.call与bind都是直接传递参数,apply传递的是数组;
原生实现call()
//call原生实现
Function.prototype.calls = function(user,...a){
// 如果没有传或传的值为空对象 user指向window
if(!user || user == null || user == undefined){
user = window;
}
//创建一个Symbol唯一值
let lyy = Symbol();
user[lyy] = this;
//执行函数并返回结果
return user[lyy](...a);
}
在创建对象检验原生call方法
function func(a,b){
console.log(this);
console.log(this.name);
console.log(a);
console.log(b);
}
const obj2 = {
name:'zth'
}
func.calls(obj2,1,2);
原生实现apply()
//apply原生实现
//apply原理一致 只是第二个参数是传入的数组
Function.prototype.applys = function(user1,args){
if(!user1 || user1 == null){
user1 == window;
}
// 创造唯一的key值 作为我们构造的context内部方法名
let lzy = Symbol();
user1[lzy] = this;
// 执行函数并返回结果
return user1[lzy](...args);
}
同样创建对象检测
function func(name,age){
console.log(this);
console.log(name);
console.log(age);
}
const obj2 = {}
func.applys(obj2,["wq",25]);
原生实现bind()
// bind原生实现
Function.prototype.binds = function(user3){
// 如果没有传或传的值为空对象 context指向window
if(typeof user3 === "undefined" || user3 === null){
user3 == window;
}
let fn = Symbol();
user3[fn] = this; //给user3添加一个方法 指向this
// 处理参数 去除第一个参数this 其它下·下·下·传入fn函数
let arg = [...arguments].slice(1); //[...xxx]把类数组变成数组,arguments为啥不是数组自行搜索 slice返回一个新数组
user3[fn](arg); //执行fn
delete user3[fn]; //删除方法
}