ES5通过以下方式实现bind函数
function.prototype.bind=function {
var self=this,
args=arguments.length 1? Array.Slice(Arguments,1 ) : null,
f=功能();
var bound=function
var context=that,length=arguments.length;
if(thisinstanceofbound )
F.prototype=self.prototype;
内容=new f;
}
var result=! args! 长度)
? self.call (上下文) )。
3360 self.apply (上下文,args length? args.concat(Array.Slice ) arguments ) : args || arguments );
return context==that? result :上下文;
(;
返回绑定;
}
测试1
var bar=function
控制台. log (this.x ) )。
}
var foo={
x: 3
}
varfunc=bar.bind(foo;
func (; //3
bar函数绑定foo的x值并输出3
bind函数中最重要的是bound函数,bound函数做了什么?
首先从上下文存储到上下文判断为this实例of bound。 什么时候会是this instanceof bound==true呢? 在测试1的情况下,this实例of bound为false,此时的this输出Window{postMessage: 、blur: 、focus: 、close: 、frames
因此,此时直接执行self.call(context,返回所执行的结果3是我们测试1的结果。
什么时候会是this instanceof bound==true呢? 另外,此时,需要使用空函数f来获取主函数的prototype。
答案是实例化。 什么时候实例化?
测试2
var bar=function
控制台. log (this.x ) )。
}
bar.prototype.name=function
this.name='name ';
}
var foo={
x: 3
}
varfunc=bar.bind(foo;
var newFunc=new func;//未定义
newFunc.name (; //name
实例化bar.bind(foo )。 此时,因为进行了new操作,所以new操作做了什么呢? 请参考new操作器中发生了什么。 因此,此时的this是新生成的bound {}对象,constructor是bound函数,所以此时的this instanceof bound==true
那么为什么bar.bind(foo )传递foo对象时是undefined而不是输出3呢? 由于new操作,当前上下文是已经新生成的newFunc函数。 如果this instanceof bound==true,则bar的prototype分配给f函数,bound函数返回new F,因此bar的prototype也分配给newFunc。
让我们来看看ES6的操作。 结果与上述示例相同。
var bar=function
控制台. log (this.x ) )。
}
bar.prototype.name=function
console.log('name ) )。
}
var foo={
x: 3
}
varfunc=bar.bind(foo;
func (; //3
//实例化
var newFunc=new func;//未定义
newFunc.name (; //name
总结:
所以bind函数一共做了什么?
如果未实例化,则在当前函数中引用传入对象的参数,然后执行当前函数并返回结果
实例化时,使用new操作生成新函数,将原始函数的prototype分配给新函数,执行新函数,然后返回新函数