(function(){
if (!Function.prototype.bind) {
alert(1);
Function.prototype.bind = function(obj){
alert(2);
var owner = this, args = Array.prototype.slice.call(arguments),
callobj = Array.prototype.shift.call(args);
return function(e){
alert(1);
e = e || top.window.event || window.event;
owner.apply(callobj, args.concat([e]));
};
};
}
})();
if (!Function.prototype.bind) {
alert(1);
Function.prototype.bind = function(obj){
alert(2);
var owner = this, args = Array.prototype.slice.call(arguments),
callobj = Array.prototype.shift.call(args);
return function(e){
alert(1);
e = e || top.window.event || window.event;
owner.apply(callobj, args.concat([e]));
};
};
}
})();
(function(){
if (!Function.prototype.bind) { //判断有没有加过bind属性
alert(1);
Function.prototype.bind = function(obj){
alert(2);
var owner = this, args = Array.prototype.slice.call(arguments),
callobj = Array.prototype.shift.call(args); //取第一参数
return function(e){
alert(1);
//判断用e取从左到右有值的第一个
e = e || top.window.event || window.event;
//函数的当前对象为callobj也就是第一个参数,并传后面的参数
owner.apply(callobj, args.concat([e]));
};
};
}
})();
检查函数原型中是否存在名叫bind的方法,如果存在什么都不执行,如果不存在就给原型加上一个bind方法。
调用bind的结果是返回一个新函数,新函数中将‘调用bind的函数的this’指定为‘调用时传到bind中的参数的第一个参数’,将‘调用bind的函数的参数’指定为‘调用时传到bind中的所有参数+e(事件对象)’。(2)可以自己做个小例子(前提是要保证if(...)可以顺利执行,可以找一个版本较低的浏览器),看一下:function foo(){
alert(this.length)
};//调用bind;
foo.bind('b','c');//因为bind方法返回一个新函数(可以通过consloe.log(foo.bind('b','c')))在控制台里检测一下,
//所以可以如下所示执行新函数。
//返回的新函数执行时,实际上是在执行:foo.apply('b',['b','c',e]),
//此时foo内部的this指向了'b'所以最后弹出的是1(字符串b的length)。
//因为foo在定义时并没有指定要传参,所以在这里['b','c',e]就没有什么意义了。
foo.bind('b','c')();//弹出:1
先谢谢阿鱼详细回答,我这么测的
Function.prototype.bind = function(obj){
var owner = this,
args = Array.prototype.slice.call(arguments);
console.log(args);//[o { num=1}, 2]
var callobj = Array.prototype.shift.call(args);//o { num=1}
console.log(args);//[2]
return function(e){
e = e || top.window.event || window.event;
console.log(e);//undifined 这里怎么回事?没有获取到event对象
owner.apply(callobj, args.concat([e]));//等同于fn.apply(o,[2,e])是吧
console.log(args.concat([e]));
};
};
function o(){
this.num = 1;
this.fn = function(arg){
alert(this.num + arg)
}.bind(this, 2);
}
var ofn = new o();
ofn.fn();
有两个问题:1、event对象没获取到,undefined..
2、事件对象在这里具体什么用途?
3,这个为函数原型新增的bind方法有什么应用场景?
js学得疏浅.谢谢解答...
我是这样测的. Function.prototype.bind = function(obj){
var owner = this,
args = Array.prototype.slice.call(arguments);
console.log(args);//[o { num=1}, 2]
var callobj = Array.prototype.shift.call(args);//o { num=1}
console.log(args);//[2]
return function(e){
e = e || top.window.event || window.event;
console.log(e);//undifined 这里怎么回事?没有获取到event对象
owner.apply(callobj, args.concat([e]));//等同于fn.apply(o,[2,e])是吧
console.log(args.concat([e]));
};
}; function o(){
this.num = 1;
this.fn = function(arg){
alert(this.num + arg)
}.bind(this, 2);
}
var ofn = new o();
ofn.fn();1、event对象没获取到,undefined..
2、事件对象在这里具体什么用途?
3,这个为函数原型新增的bind方法有什么应用场景?
函数原型新增的方法为了调用方便
下面例子:给body的onclick邦定一个方法,响应是可以传参数点我
<script>
(function(){
if (!Function.prototype.bind) {
Function.prototype.bind = function(obj){
var owner = this, args = Array.prototype.slice.call(arguments),
callobj = Array.prototype.shift.call(args);
return function(e){
alert(1);
e = e || top.window.event || window.event;
owner.apply(callobj, args.concat([e]));
};
};
}
})();
function OnClick(a,b,c){
alert( this.tagName + ':'+( a+b+c ) );
}
document.body.onclick=OnClick.bind(document.body,1,2,3);
</script>
<input type="button" name="NotBind" id= "notBind" value="Not bind">
<input type="button" name="Bind" id= "bind" value="Bind"><SCRIPT type="text/javascript">
<!--
(function(){
if (!Function.prototype.bind) {
alert(1);
Function.prototype.bind = function(obj){
alert(2);
var owner = this, args = Array.prototype.slice.call(arguments),
callobj = Array.prototype.shift.call(args);
return function(e){
alert(1);
e = e || top.window.event || window.event;
owner.apply(callobj, args.concat([e]));
};
};
}
})();var ob = {
name:"'This' is the object ob, not the button"
}var find= function (name) {
return document.getElementById(name);
}find("notBind").onclick= function () {
alert(this.name);
}find("bind").onclick= (function () {
alert(this.name);
}).bind(ob);
//-->
</SCRIPT>
6楼是用bind给input按钮添加了单击事件函数(弹出name值),原代码我们不动,只在“find("bind")...”这个地方加一点点东西,如下://修改之前的原代码:
find("bind").onclick= (function () {
alert(this.name);
}).bind(ob);//修改之后:传入了参数e,并加了一行alert(e.clientX)
find("bind").onclick= (function (e) {
alert(this.name);
//下面为新代码,client是事件对象的属性,
//意思是事件发生时鼠标相对于屏幕的横坐标的值,在这里就是单击按钮时鼠标的横坐标
alert(e.clientX);
}).bind(ob);修改后,单击#bind按钮,新代码成功执行,既弹出了name的值,也弹出了鼠标坐标。其实我们加的事件对象e就来自在原型中定义bind方法时“return function(e){...}”中的e。
下面我们来验证一下,很简单去掉bind定义时传入的e: return function(){//去掉了参数e
alert(1);
e = e || top.window.event || window.event;
owner.apply(callobj, args.concat([e]));
};然后,当再点击#bind按钮时,发现代码不执行了,而且浏览器报错"e is not defined";这恰恰能验证e来自bind定义时返回的新函数中的参数e。其实到这里,就比较清晰了://给按钮绑定的事件函数并不是
//find("bind").onclick=
(function (e) {
alert(this.name);
alert(e.clientX)
}).bind(ob)//而是
function(e){
e = e || top.window.event || window.event;
(function (e) {
alert(this.name);
alert(e.clientX)
}).apply(ob, [e]);
}
//所以按钮的单击事件对象e是存在于这个函数中的而不是onclick后面的函数,如果想进行关于事件对象e的操作只能在bind返回的新函数中进行。但是bind是为所有函数定义的公有方法,不可能为了某个按钮的操作在里面进行对e的操作,所以把e(代码中的(obj,[e]))传给了调用bind方法的函数(也就是onclick后的函数),这样就可以在自己定义的函数里对e进行任意操作了。
(2)之前在一些较早的js类库里,都有相似的bind扩展方法。而且,事实上在javascript-1.8.5版本后就已经在函数原型中增加了bind方法(部分浏览器不支持比如ie6-8),该bind方法与楼主的bind有点出入,不过主要功能也是为了转移this。
楼主可以参考下:
https://developer.mozilla.org/zh-CN/docs/JavaScript/Reference/Global_Objects/Function/bind(英文版--Mozilla)
http://msdn.microsoft.com/zh-cn/library/ie/ff841995(v=vs.94).aspx(汉译--MS)