@@ -274,3 +274,128 @@ createXHR运行之后,会被重新改写了,之后的createXHR是改写后
274274
275275函数绑定要创建一个函数,可以在特定的 this 环境中以指定参数调用另一个函数。该技巧常常和回调函数与事件处理程序一起使用,以便在将函数作为变量传递的同时保留代码执行环境。
276276
277+ <script>
278+ //这里是事件工具库;
279+ var EventUtil = {
280+ addHandler: function (element, type, handler) {
281+ if (element.addEventListener) {
282+ element.addEventListener(type, handler, false);
283+ } else if (element.attachEvent) {
284+ element.attachEvent("on" + type, handler);
285+ } else {
286+ element["on" + type] = handler;
287+ }
288+ },
289+ removeHandler: function (element, type, handler) {
290+ if (element.removeEventListener) {
291+ element.removeEventListener(type, handler, false);
292+ } else if (element.detachEvent) {
293+ element.detachEvent("on" + type, handler);
294+ } else {
295+ element["on" + type] = null;
296+ }
297+ },
298+
299+ getEvent: function (event) {
300+ return event ? event : window.event;
301+ },
302+ getTarget: function (event) {
303+ return event.target || event.srcElement;
304+ },
305+ preventDefault: function (event) {
306+ if (event.preventDefault) {
307+ event.preventDefault();
308+ } else {
309+ event.returnValue = false;
310+ }
311+ },
312+ stopPropagation: function (event) {
313+ if (event.stopPropagation) {
314+ event.stopPropagation();
315+ } else {
316+ event.cancelBubbles = true;
317+ }
318+ },
319+ getRelatedTarget: function (event) {
320+ if (event.relatedTarger) {
321+ return event.relatedTarget;
322+ } else if (event.toElement) {
323+ return event.toElement;
324+ } else if (event.fromElement) {
325+ return event.fromElement;
326+ } else { return null; }
327+
328+ }
329+
330+ };
331+ //这里是绑定函数的代码;
332+ var handler={
333+ message:"Event handler",
334+ handleClick:function(e){
335+ console.log(this.message);
336+ }
337+ };
338+ var oBtn=document.getElementById("btn");
339+ EventUtil.addHandler(oBtn,"click",handler.handleClick);
340+
341+ </script>
342+
343+ 点击后,输出的是undefined;并不是"Event hanler";** 原因是没有保存handler.handClick()的运行环境** ,this对象最后指的是btn这个ID的按钮;而非hanler; 可以通过代码验证;
344+
345+ var oBtn=document.getElementById("btn");
346+ oBtn.message="这是ID为btn的message属性";
347+ EventUtil.addHandler(oBtn,"click",handler.handleClick);
348+
349+ > 解决办法:包一层函数
350+
351+ var oBtn=document.getElementById("btn");
352+ oBtn.message="这是ID为btn的message属性";
353+ EventUtil.addHandler(oBtn,"click",function(e){
354+ handler.handleClick(e)
355+ });
356+
357+ 这个解决方案在 onclick 事件处理程序内使用了一个闭包直接调用 handler.handleClick() 。当然,这是特定于这段代码的解决方案。创建多个闭包可能会令代码变得难于理解和调试。因此,很多JavaScript 库实现了一个可以将函数绑定到指定环境的函数。这个函数一般都叫 bind() 。
358+
359+ function bind(fn,context){
360+ return function(){
361+ return fn.apply(context,arguments);
362+ }
363+ }
364+ //这里是绑定函数的代码;
365+ var handler={
366+ message:"Event handler",
367+ handleClick:function(e){
368+ console.log(this.message+":"+ e.type);
369+ }
370+ };
371+ var oBtn=document.getElementById("btn");
372+ oBtn.message="这是ID为btn的message属性";
373+ EventUtil.addHandler(oBtn,"click",bind(handler.handleClick,handler));
374+
375+
376+ handler.handleClick() 方法和平时一样获得了 event 对象,因为所有的参数都通过被绑定的函数直接传给了它。
377+
378+ ECMAScript 5 为所有函数定义了一个原生的 bind() 方法,进一步简单了操作。换句话说,你不用再自己定义 bind() 函数了,而是可以直接在函数上调用这个方法。
379+
380+ 通过输出到控制台查看下;
381+
382+ console.dir(bind);
383+
384+ ![ ] ( http://i.imgur.com/QtSzMG9.png )
385+
386+ //这里是绑定函数的代码;
387+ var handler={
388+ message:"Event handler",
389+ handleClick:function(e){
390+ console.log(this.message+":"+ e.type);
391+ }
392+ };
393+ var oBtn=document.getElementById("btn");
394+ oBtn.message="这是ID为btn的message属性";
395+ //EventUtil.addHandler(oBtn,"click",bind(handler.handleClick,handler));
396+ EventUtil.addHandler(oBtn,"click",handler.handleClick.bind(handler));//原生的bind方法;
397+
398+ ** 原生的 bind() 方法与前面介绍的自定义 bind() 方法类似,都是要传入作为 this 值的对象。支持原生 bind() 方法的浏览器有 IE9+、Firefox 4+和 Chrome。**
399+
400+ 只要是将某个函数指针以值的形式进行传递,同时该函数必须在特定环境中执行,被绑定函数的效用就突显出来了。它们主要用于** 事件处理程序以及 setTimeout() 和 setInterval() ** 。然而,被绑定函数与普通函数相比有更多的开销,它们需要更多内存,同时也因为多重函数调用稍微慢一点,所以最好只在必要时使用。
401+
0 commit comments