• 函数包装


    函数包装是一个的用来封装函数功能的技巧。
    如果想要继承或者创建一个新的函数的时候,通过函数包装可直接实现。
    最有价值的一个场景是:在我们想要重写(override)一些已经存在的函数的情况下, 并且可以保持在原始函数中那些有用的部分可以在被包装后仍然有效。

    另外一个普遍的场景是:兼容不同的浏览器。
    例如在Opera浏览器中,有一个获取title属性的bug。
    Prototype类库采用了函数包装这个技术来对付这个bug。

    为了防止在readAttribute()函数中,过多的出现if/else这样的代码快(这是一个比较丑陋,并且不是一个特别好的分割逻辑的方式)。
    Prototype选择利用函数包装(function wrapping)来重写(override)那个老的方法,但是原始函数中的那些正常的逻辑还应该有效。

    function wrap(object, method, wrapper){ 
        var fn = object[method]; //#1 
        return object[method] = function(){ //#2 
            return wrapper.apply(this, [fn.bind(this)].concat( 
                Array.prototype.slice.call(arguments))); 
        }; 
    };
    
    // Example adapted from Prototype 
    if (Prototype.Browser.Opera){ //#3 
        wrap(Element.Methods, "readAttribute",
            function(original, elem, attr){ 
                return attr == 'title' ? elem.title : original(elem, attr);
            });
    }

    //#1 缓存原始函数
    //#2 返回新的包装函数
    //#3 实现函数包装

    我们来分析一下wrap()函数是如何工作的。
    在传入wrapp()的参数中包括:
    1.一个基础的对象(object)
    2.这个基础对象想要被包装的方法(method)
    3.新的包装函数(wrapper)

    首先,我们将原始方法保存在变量fn中(#1);
    我们在后面会通过匿名函数的闭包(anonymous function‟s closure)来调用它。
    然后我们用一个新的函数来重写这个方法(#2)
    这个新的函数执行了之前传进来的wrapper函数(通过一个闭包),并且传给它一个重新构造的参数列表.
    在构建这个参数列表时,我们想让第一个参数是我们正在重写的原始函数(original function),
    这样一来,我们创建一个数组来连接原始函数(原始函数的上下文已经被绑定,通过bind()函数,我们之前在例5.3中创建的,同样适用于包装函数),然后将原始参数追加到这个数组中。
    在apply()函数中,如我们所见,用这个数组作为了他的参数列表。

    结论就是,wrap()函数是一个可以重用的函数,我们可以用一种比较隐蔽的方式, 来重写任何对象的方法中的已有的功能。 这又是一个彰显闭包威力的案例。

  • 相关阅读:
    两栏自适应布局
    说说bfc 和 HasLayout
    春联式弹动广告
    Centos7安装完毕后重启提示Initial setup of CentOS Linux 7 (core)的解决方法
    2016年新剧《欢乐颂》里面的经典台词
    硬盘怎么保养
    如何保养与维护笔记本硬盘
    仔细看完,你会成为微信高手
    电脑之间用网线直接连接起来快速传送大文件技巧
    阿里云9折优惠码 GQH4IT 使用方法如下:
  • 原文地址:https://www.cnblogs.com/gongshunkai/p/6654789.html
Copyright © 2020-2023  润新知