zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    bzoj-2748 2748: [HAOI2012]音量调节(dp)
    bzoj-2338 2338: [HNOI2011]数矩形(计算几何)
    bzoj-3444 3444: 最后的晚餐(组合数学)
    codeforces 709E E. Centroids(树形dp)
    codeforces 709D D. Recover the String(构造)
    codeforces 709C C. Letters Cyclic Shift(贪心)
    codeforces 709B B. Checkpoints(水题)
    codeforces 709A A. Juicer(水题)
    Repeat Number
    hdu 1003 Max Sum (动态规划)
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/1602993.html
Copyright © 2011-2022 走看看