1.实现call2函数
const obj = {
name: '小花',
};
const obj1 = {
name: '小草',
};
function test(a, b) {
console.log(this.name);
console.log(a + b );
}
//模拟call实现
Function.prototype.call2=function(context){
if(context == null){
var context = Window;
}else{
var context = Object(context);
}
if(typeof this != 'function'){
throw TypeError(this + 'is not a function');
}
var fn = Symbol();
context[fn] = this;
//取传入的参数
let args = [];
for (let index = 1; index < arguments.length; index++) {
args.push('arguments['+ index + ']')
}
//执行函数
var result = eval('context[fn]('+args+')');
return result;
}
test.call(obj1,1,10)
test.call2(obj1,1,5);
2.实现apply2函数
const obj = {
name: '小花',
};
const obj1 = {
name: '小草',
};
function test(a, b) {
console.log(this.name);
console.log(a + b );
}
//模拟apply实现
Function.prototype.apply2=function(context,arr){
if(context == null){
var context = Window;
}else{
var context = Object(context);
}
if(typeof this != 'function'){
throw TypeError(this + 'is not a function');
}
var fn = Symbol();
context[fn] = this;
var result
//执行函数
if(arr){
result = eval(context[fn](...arr))
}else{
context[fn]()
}
return result;
}
test.apply2(obj,[1,50]);
3.在call和apply的基础上实现applyFn函数
const obj = {
name: '小花',
};
const obj1 = {
name: '小草',
};
function test(a, b) {
console.log(this.name);
console.log(a + b );
}
//模拟bind实现
Function.prototype.bindFn = function(context){
if(typeof this != 'function'){
throw TypeError(context + 'is not a function');
}
//获取第一次的对象和传过来的参数
var self = this;
//去掉arguments类数组中第一个元素,也就是this的值,得到第一次传入的参数args1
var args1 = [].slice.call(arguments,1)
//返回一个已经绑定好this值的bound函数,并且加入第二次传入的参数
var bound = function(){
var args2 = [].slice.call(arguments)
return self.apply(context,args1.concat(args2))
}
return bound;
}
var bound = test.bindFn(obj,1);
bound(20);