javascript中的函数绑定
2015-10-27 14:11
656 查看
首先我们来看看jQuery中的proxy函数如何实现函数绑定的:
例子3:(重点不是闭包,而是修正this,this在这里的指向就是调用者handler)
例4:
例5:原生的ECMAScript5的bind方法
调用者是一个函数,参数是一个对象,表示将这个函数绑定到这个参数中,从而在这个函数中可以用this访问这个参数对象!
其实关于关于bind方法的博客是很多的,但是从他们对bind的描述来说我们可以知道,bind方法和上面的proxy函数内部具有相似的逻辑。拿着这个函数作为下次真正调用时候执行,把bind时候传入的多于一个的参数作为局部变量args保存下来,然后把它和返回新函数调用的参数组合起来,作为新的参数传入到新函数中!
proxy: function( fn, context ) { var args, proxy, tmp; //这说明:在直接调用proxy得到新的函数的时候就可以传入多余的参数,从第三个参数以后会被当作额外的参数来处理 args = slice.call( arguments, 2 ); proxy = function() {//这里的arguments就是真正函数调用的时候传入的参数,通过把两次的参数结合调用最终返回的函数! return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); }; return proxy; }例子1:
//在当前页面内追加换行标签和指定的HTML内容 function w( html ){ document.body.innerHTML += "<br/>" + html; } var name = "Hello"; function foo( a, b,c,d ){ w( this.name ); w( a + b+c+d ); } var obj = { name: "CodePlayer", age: 18 }; var proxy = $.proxy( foo, obj, 5, 10 ); //调用proxy函数的时候返回了一个新的函数,该函数的context就是obj,同时因为他是通过闭包完成,所以他会得到外层的args也就是调用,$.proxy时候传入的多余的参数!同时通过闭包也能够访问外层的参数的fn! // 代理调用foo()函数,此时其内部的this指向对象obj proxy(5,6); // CodePlayer // 26例子2:
var handler={ message:"event handle", handleCick:function(event) { alert(this.message); } } var btn=document.getElementById("button"); //这时候打印"undefined",因为这里面的this指向了button对象,在IE8中会指向window //buttom对象没有message属性,所以打印undefined! btn.onclick=handler.handleCick;note:在IE8中会指向window,其它浏览器指向button!
例子3:(重点不是闭包,而是修正this,this在这里的指向就是调用者handler)
var handler={ message:"event handle", handleCick:function(event) { alert(this.message); } } //那么为什么说这句话修改了this呢,因为this指向的就是调用者!而在这个函数中调用者就是handler //至于为什么把event传入到handleClick中,是因为在handleClick中可以获取到这个事件的具体信息! var btn=document.getElementById("button"); btn.onclick=function(event) { handler.handleCick(event); }note:例子2和例子3都是针对特定代码进行绑定对象修正的,不具有共性,从而才引入了函数绑定的概念!
例4:
function show(n1,n2) { alert(n1); alert(n2); alert(this); } $.proxy(show ,document,3,4)();//直接用括号调用 $.proxy(show,document,3)(4);//调用的时候传入4作为参数note:上面两种调用方式都是相等的,this指向了document对象。其实在jQuery的源码中处处有函数绑定的影子,下面就是在$.when函数中的代码片段
.done( updateFunc( i, resolveContexts, resolveValues ) )note:对于特定的Deferred对象,我们在他的回调集合中加入了updateFunc方法调用后的结果,这个结果也是一个函数,而这个返回的函数可以访问updateFunc函数中的所有的参数信息!如i,resolveContexts,resolveValues等!当你用resolve方法传入参数的时候就会被传递到updateFunc调用返回的新的参数中作为arguments!
例5:原生的ECMAScript5的bind方法
调用者是一个函数,参数是一个对象,表示将这个函数绑定到这个参数中,从而在这个函数中可以用this访问这个参数对象!
var handler={ message:"event handle", handleCick:function(event) { alert(this.message); } } var btn=document.getElementById("button"); //这时候就会打印"event handle" btn.onclick=handler.handleCick.bind(handler); //主要用于事件处理程序,setTimeout,setInterval,然而和普通函数相比 //有更多的内存开销,而且因为是多重函数调用稍微慢一点!例6:
其实关于关于bind方法的博客是很多的,但是从他们对bind的描述来说我们可以知道,bind方法和上面的proxy函数内部具有相似的逻辑。拿着这个函数作为下次真正调用时候执行,把bind时候传入的多于一个的参数作为局部变量args保存下来,然后把它和返回新函数调用的参数组合起来,作为新的参数传入到新函数中!
var slice=Array.prototype.slice; //返回的是一个本地call方法,这个call方法的上下文是slice方法 //如果你给这个本地call方法传入参数,那么这个参会会被送到原生的call方法中去执行! var nativeCall=Function.prototype.call.bind(slice); //打印true,这个nativeCall方法的上下文是slice方法! alert(nativeCall({0:"xx",1:"ccc"}) instanceof Array);下面这个例子的本地call方法的上下文就是concat方法(要调用谁的方法就把谁作为上下文):
var concat=Array.prototype.concat; //返回的是一个本地call方法,这个call方法的上下文是slice方法 //如果你给这个本地call方法传入参数,那么这个参会会被送到原生的call方法中去执行! var nativeCall=Function.prototype.call.bind(concat,[1,2,3]); //打印true,这个nativeCall方法的上下文是slice方法! alert(nativeCall([4,5,6]));
相关文章推荐
- 2015-10-27 js
- js 复制、全选功能
- IIS访问.json/.txt文件总是提示 “无法找到该页” IIS添加MIME扩展类型及常用的MIME类型列表
- angular JS 拦截器总结
- Angular JS 自动解析绑定内容中的html
- Javascript继承机制的设计思想
- 说说JSON和JSONP,也许你会豁然开朗
- js中substring和substr的用法
- js控制audio
- JS判断URL尾缀格式
- js阻止事件冒泡
- JS实现自动倒计时30秒后按钮才可用
- javascript 相关积累
- js字符串转换成数字,数字转换成字符串
- 一个关于js代码如何获取服务器时间问题
- js两次一样的正则表达式,结果却不同
- DOM创建节点和添加属性
- 将数字转化成一定精度的小数(JS函数)
- JavaScript开发规范要求
- JavaScript 通过HTML的FileReader把图片转成base64