准备两个对象用于测试
const lvs={
name:"MaxLoong",
age:18,
say:function(...args){
console.log(this);
console.log(`姓名:${this.name},年龄:${this.age},参数:${args}`)
}
}
const xxx={
name:"xxx",
age:1000000
}
封装call方法
Function.prototype.myCall = function(ret, ...args) {
if(typeof this !== 'function') throw new TypeError("Please use the correct type");
ret = ret || window;
ret = typeof ret !== 'object' ? new Object(ret) : ret;
const _key = Symbol();
ret[_key] = this; //将this函数 赋值给ret
ret[_key](...args);
delete ret._key;
}
lvs.say.call("baj")
lvs.say.myCall("baj")
这里可以看到还是有问题的,当参数为一个字符串的时候,new 出来的对象中比原方法多出了一个Symbol()
封装apply方法
Function.prototype.myCall = function(ret, ...args) {
if(typeof this !== 'function') throw new TypeError("Please use the correct type");
ret = ret || window;
ret = typeof ret !== 'object' ? new Object(ret) : ret;
const _key = Symbol();
ret[_key] = this; //将this函数 赋值给ret
ret[_key](...args);
delete ret._key;
}
lvs.say.call("baj")
lvs.say.myCall("baj")
仍然多了Symbol()
Function.prototype.myBind = function(ret,...args){
if(typeof this !== 'function') throw new TypeError("Please use the correct type");
const _this = this;
return function() {
const newArgs =args.concat(...arguments);
_this.myCall(ret, newArgs);
}
}
var a = lvs.say.myBind(xxx);
var b = lvs.say.bind(xxx);
console.log(a());
console.log(b());
bind方法看起来是相同的
总结
并没有经过严谨的测试,欢迎留言。
- 因为经常被用于面试题,如有需要可以尝试封装