宁波网站优化找哪家,深圳网站 商城制作,亚马逊网站风格,设计开发输入清单分享一个基础面试题---手写call 手写call笔记第一步第二步第三步 手写call笔记 call()#xff1a;在使用一个指定的this值和若干个指定的参数值的前提下调用某个函数或方法。 let foo {value:1
};
function bar(){console.log(this.value);
}
bar.call(foo);//1注意两点… 分享一个基础面试题---手写call 手写call笔记第一步第二步第三步 手写call笔记 call()在使用一个指定的this值和若干个指定的参数值的前提下调用某个函数或方法。 let foo {value:1
};
function bar(){console.log(this.value);
}
bar.call(foo);//1注意两点
call改变了this的指向指向到foo;bar 函数执行了
第一步
上述方式等同于
let foo {value:1;bar:function(){console.log(this.value)}
};
foo.bar();//1这个时候this就指向了foo,但是这样却给foo对象本身添加了一个属性所以我们用delete再删除它即可。 所以我们模拟的步骤可以分为
将函数设为对象的属性执行该函数删除该函数
以上个例子为例就是
//第一步
//fn 是对象的属性名反正最后也要删除它所以起什么名字都可以。
foo.fn bar
//第二步
foo.fn()
//第三步
delete foo.fn根据上述思路提供一版
//第一版
//将foo作为context参数传递
Function.prototype.call2 function(context){//首先要获取调用call的函数用this可以获取//将函数设为对象的属性context.fn this;//执行该函数context.fn();//删除该函数delete context.fn;
}第二步
call除了可以指定this还可以指定参数
var foo {value:1
};
function bar(name,age){console.log(name);console.log(age);console.log(this.value);
}
bar.call(foo,ken,18);可以从Arguments对象中取值取出第二个到最后一个参数然后放到一个数组里。 上述代码的Arguments中取第二个到最后一个参数。
//以上个例子为例此时的arguments为
// arguments {
// 0:foo,
// 1:ken,
// 2:18,
// length:3
//}
//因为arguments是类数组对象所以可以用for循环
var args [];
for(var i 1,len arguments.length;ilen;i){args.push(arguments[i]);
}
//执行后args 为[arguments[1],arguments[2],arguments[3]]接下来使用eval拼接成一个函数
eval(context.fn(args))考虑到目前大部分浏览器在console中限制eval的执行也可以使用rest 此处代码为
//第二版
Function.prototype.call2 function(context){context.fn this;let arg [...arguments].slice(1);context.fn(...arg);delete context.fn;
}
//测试一下
var foo {value:1
};
function bar(name,age){console.log(name);console.log(age);console.log(this.value);
}
bar.call2(foo,ken,18)
//ken
//18
//1第三步
this参数可以传null,当为null的时候视为指向window 举个例子
var value 1;
function bar(){console.log(this.value);
}
bar.call(null);//1针对函数可以实现返回值
var obj {value:1
};
function bar(name,age){return{value:this.value,name:name,age:age}
}
console.log(bar.call(obj,ken,18));
//Object{
// value:1,
// name:ken,
// age:18
//}第三版
Function.prototype.call3function(context){//1.this为null也可以写为context ?? window 或者 contextcontext??windowvar context context || window;context.fn this;let arg [...arguments].slice(1)let result context.fn(...arg)delete context.fn//2.有返回值return result
}
//测试一下
var value 2;
var obj {value:1
}
function bar(name,age){console.log(this.value);return{value:this.value,name:name,age:age}
}
bar.call3(null);//2
console.log(bar.call3(obj,ken,18));//1
//Object{
// value:1,
// name:ken,
// age:18
//}这边给出的简化写法
Function.prototype.call3 function(context,..args){//判断是否是undefined和nullif (typeof context undefined || context null){context window}//每个从Symbol()返回的symbol值都是唯一的let fnSymbol Symbol()context[fnSymbol] this//入参...args [...arguments].slice(1);let fn context[fnSymbol](...args)//删除目的是不污染原来数据delete context[fnSymbol]return fn
}可能会有新手宝宝们看完觉得还是很晦涩可以动手写一遍试试不行再多写两遍好记性不如烂键盘脑子再快也不如肌肉记忆哈哈哈~ 当然也可以留言讨论啦~