目录
js的call方法非常强大,说的通俗点,就是可以借窝下蛋,这次就先来看看call方法是什么作用,如何使用,然后在模拟一下call方法。
js的call方法非常强大,说的通俗点,就是可以借窝下蛋,这次就先来看看call方法是什么作用,如何使用,然后在模拟一下call方法。
先看一下语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]])
参数
thisObj
可选项。将被用作当前对象的对象(如果没有传、null、undefined 都会被默认为全局对象)。
arg1, arg2, , argN
可选项。将被传递方法参数序列。
下面来看一下具体用法
var person={
name:"人类",
sayHi:function(){
return this.name+" 在向你问好!";
}
}
console.log(person.sayHi());
此时输出:人类 在向你问好!【这是我们常用的调用方法的方式】
再定义个pig对象,但是pig对象并没有sayHi方法,我们可以通过call来借用:
var pig={
name:'小猪'
}
console.log(person.sayHi.call(pig));//小猪 在向你问好!
此时我们可以看到pig对象借用了sayHi方法,并且从打印的“小猪”可以看出确实是pig对象使用了sayHi方法。
现在自己尝试来写一下call方法
Function.prototype.myCall=function(){
var ret;
var args=arguments;
if(args.length==0){
return this();//window
}else{
var context,arg,newArgs;
context = args[0];//第一个参数是作为上下文
if(context==null){//处理null 和 undefined
return this();//window
}
context[this.name]=this;
return context[this.name]()
}
return ret;
}
console.log("-----------------")
console.log(person.sayHi.myCall(pig));//小猪 在向你问好!
正常打印,现在再来试一下不传参数,以及传入null、undefined的情况:
console.log(person.sayHi.call(pig));
console.log(person.sayHi.call());
console.log(person.sayHi.call(undefined));
console.log(person.sayHi.call(null));
console.log("-----------------")
console.log(person.sayHi.myCall(pig));
console.log(person.sayHi.myCall());
console.log(person.sayHi.myCall(undefined));
console.log(person.sayHi.myCall(null));
输出:
小猪 在向你问好!
在向你问好!
在向你问好!
在向你问好!
-----------------
小猪 在向你问好!
在向你问好!
在向你问好!
在向你问好!
打印是一样的,加入参数的写一下,加入参数的话要稍作处理
Function.prototype.myCall=function(){
var ret;
var args=arguments;
if(args.length==0){
return this();//window
}else{
var context,arg,newArgs;
context = args[0];//第一个参数是作为上下文
if(context==null){//处理null 和 undefined
return this();//window
}
if(typeof context!=='object'){
context = {};
}
context[this.name]=this;
var fn = this.name+"(";
for(var i=1,len=args.length;i<len;i++){
arg = args[i];
if(i===1){
fn+="'"+arg+"'";
}else{
fn+=",'"+arg+"'";
}
}
fn +=")";
ret= eval("context."+fn);
}
return ret;
}
要处理成这样,来验证一下结果:
可以看到结果是一样的,接下来是完整的代码:
var person={
name:"人类",
sayHi:function(a,b){
return this.name+" 在向你问好!"+a+" "+b;
}
}
//console.log(person.sayHi());
var pig={
name:'小猪'
}
Function.prototype.myCall=function(){
var ret;
var args=arguments;
if(args.length==0){
return this();//window
}else{
var context,arg,newArgs;
context = args[0];//第一个参数是作为上下文
if(context==null){//处理null 和 undefined
return this();//window
}
if(typeof context!=='object'){
context = {};
}
context[this.name]=this;
var fn = this.name+"(";
for(var i=1,len=args.length;i<len;i++){
arg = args[i];
if(i===1){
fn+="'"+arg+"'";
}else{
fn+=",'"+arg+"'";
}
}
fn +=")";
ret= eval("context."+fn);
}
return ret;
}
console.log(person.sayHi.call(pig));
console.log(person.sayHi.call());
console.log(person.sayHi.call(undefined));
console.log(person.sayHi.call(null));
console.log(person.sayHi.call(pig,'你好啊'));
console.log(person.sayHi.call(pig,'你好啊','大侠'));
console.log("-----------------")
console.log(person.sayHi.myCall(pig));
console.log(person.sayHi.myCall());
console.log(person.sayHi.myCall(undefined));
console.log(person.sayHi.myCall(null));
console.log(person.sayHi.myCall(pig,'你好啊'));
console.log(person.sayHi.myCall(pig,'你好啊','大侠'));
如果想要在没有传参的情况下,打印不出现undefined,稍作处理既可!
打完收工,改天来写一下apply方法!
距离上次写文章已经这么多年了,自己感慨一下吧