• javascript wrapper函数


    在设计javascript的继承体系时,有一个重要需求,方法链。通俗地说,说是在方法中调用父类的同名方法。类似java的this.super().method()。如何把父类的同名方法包装到子类中呢?这就要用到wrapper函数。之所以叫wrapper,而不是wrap,因为它比wrap更加wrapper。比如像Ext那种深度继承的结构中,如果父类没有找祖父,祖父没有找曾祖父,沿着原型链层层上溯,以获取它所需要的功能。此外,wrapper函数在jQuery也有应用,好像分为三种wrapAll,wrapinner,wrap,专门用来对付IE的table或其他DOM。可能还有其他用处,不管了,先看如何实现它。

    一个普通的函数

     
        var greeting = function(world){
          return "hello " + world +"!";
        };
        alert(greeting("world"));
    

    我们把它塞进更深一层的作用域,非bind函数。

     
        var wrap= function(fn){
          return function(){
            return fn.apply(null,arguments);
          };
        };
    

    但这只是延迟了它的执行时间而已。上面函数中的null,也可以换成window。

     
        var wrap= function(fn){
          return function(){
            return fn.apply(window,arguments);
          };
        };
    

    因为总要人去调用函数的,null没有此能力,就由window上。现在我们就是要在这个位置上做文章,把换成this。如果没有进一步的改进,这里的this还是window的替身。下面就开始复杂了,先分解一下写法,降低阅读难度,就像jQuery那样把它掰成三部分:

     
        var wrapper= function(fn){//这里改一下名。
          var temp =  function(){
            return fn.apply(this,arguments);
          };
          return temp;
        };
    
     
        //fn为原函数
        //temp为改装了的函数
        //wrapper为包装工厂,只运作一次
        //wrap为改装了的函数的属性,它的参数和wrapper一样为函数,但能运行无数次,
        //把原改装了的函数内置为新增函数的内部函数。
        var wrapper= function(fn){
          var temp =  function(){
            return fn.apply(this,arguments);
          };
          temp.wrap = function(callback){
            var prev = fn;
            fn = function(){
              return callback.apply(prev,arguments);
            };
          };
          return temp;
        };
    

    这样就可以如下神奇效果:

    可以看出,this总是为原来的同名函数(p),也就是说,我们可以称之为父方法,这样也super关键字或者相关的代替品也不用了,轻松调用原来覆盖了父类的方法。因此jQuery同学单是用它来处理DOM真是大材小用。Prototype同学就做得不错了,不过代码写得比较艰涩:

     
      wrap: function(wrapper) {
        var __method = this;
        return function() {
          return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
        }
      },
    

    它的方法链设计:

     
        for (var i = 0, length = properties.length; i < length; i++) {
          var property = properties[i], value = source[property];
          if (ancestor && Object.isFunction(value) &&
              value.argumentNames().first() == "$super") {
            var method = value;
            value = (function(m) {
              return function() { return ancestor[m].apply(this, arguments) };
            })(property).wrap(method);
    
            value.valueOf = method.valueOf.bind(method);
            value.toString = method.toString.bind(method);
          }
          this.prototype[property] = value;
        }
    

    相关文档:http://www.prototypejs.org/learn/class-inheritance

  • 相关阅读:
    网络流24题总结和题解
    NOIP复习之1 数学数论
    BZOJ3301 P2524 UVA11525 算法解释康托展开
    线段树与树状数组的综合运用
    P2261 bzoj1257 [CQOI2007]余数求和
    BZOJ 1968_P1403 [AHOI2005]约数研究--p2260bzoj2956-模积和∑----信息学中的数论分块
    P1064 金明的预算方案
    洛谷p1002 过河卒
    Luogu P3014 [USACO11FEB]牛线Cow Line
    Luogu P3927 SAC E#1
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/1602993.html
Copyright © 2020-2023  润新知