代码之家  ›  专栏  ›  技术社区  ›  Pim Jager

如何创建类似jquery的$()包装函数?

  •  0
  • Pim Jager  · 技术社区  · 16 年前

    我正在创建一个小的代码插件,它允许你用数组做一些事情。我不希望使用原型构造将函数添加到数组对象中,我希望人们可以这样做:

    arrayFunction( [1, 2, 3] ).someSpecialArrayFunction();
    

    从而使法线数组对象保持不变。

    var arrayFunction = window.arrayFunction = function(array) {
        return new arrayFunction.fn.init(array);
    }
    arrayFunction.fn = arrayFunction.prototype = {
        init: function(array){
            this.a = array;
            //should I return something here?
        },
        someSpecialArrayFunction: function(){
            //Super cool custom stuff here.
        }
    }
    

    然而,这显然不起作用。在init函数()中应该发生什么?

    现在的错误是,当我尝试时:

     arrayFunction(array).someSpecialArrayFunction();
    

    我们应该怎么做?

    编辑

    还有,我只是想,如果它也支持Chang,那该有多棒,你会怎么做?

    6 回复  |  直到 16 年前
        1
  •  2
  •   Luca Matteis    16 年前

    或者简单地说:

    var arrayFunction = function(array) {
        var someSpecialArrayFunction = function() {
            // do something with array
        };
        return {
            someSpecialArrayFunction: someSpecialArrayFunction
        }
    };
    arrayFunction( [1, 2, 3] ).someSpecialArrayFunction();
    

    尽管在这方面要小心,但如果最终使用了太多的方法,那么使用原型可能会更好。

        2
  •  1
  •   Pat    16 年前

    我不确定这是获得所需的最佳语法,但我想这是一个精简的示例。。。无论如何,这里有一个快速的方法让它工作

    var arrayFunction = window.arrayFunction = function(array) {
        return new arrayFunction.fn.init(array);
    }
    arrayFunction.fn = arrayFunction.prototype = {
        init: function(array){
            var a = array;
            return  {
                someSpecialArrayFunction: function(){
                    alert (a.join(' - ') ); //Super cool custom stuff here.
                }
            };
        },
    }
    arrayFunction( [1, 2, 3] ).someSpecialArrayFunction();
    
        3
  •  0
  •   Community CDub    7 年前

    斯科蒂 answer 看起来不错。

    要考虑的另外一件事是使用 flyweight pattern 而不是每次调用包装器时都返回一个新的对象实例。ExtJS函数 Ext.fly

        4
  •  0
  •   Dylan Beattie    16 年前

    试着这样做:

    var mathWrapper = function(array) {
        return {
            mean : function(){
                if (array.length == 0) return(0);
                var total = 0;
                for (var i = 0; i < array.length; i++) total += array[i];
                return(total / array.length);
            },
        };
    }
    

    document.write(mathWrapper([1,2,3,4,5,6]).mean());
    

    应返回数组元素的平均值。

        5
  •  0
  •   Christoph    16 年前

    如果你不想改变 Array.prototype ,唯一真正可行的解决方案是将方法添加到特定的数组对象:

    function doSomething() {}
    function doOther() {}
    
    function wrap(array) {
        array.doSomething = doSomething;
        array.doOther = doOther;
        return array;
    }
    

    doSomething() doOther() 在内部 wrap()

    更复杂的变体如下所示:

    function doSomething() {}
    function doOther() {}
    
    function wrap(array) {
        if(this instanceof arguments.callee) {
            this.doSomething = doSomething;
            this.doOther = doOther;
        }
        else {
            arguments.callee.prototype = array;
            return new arguments.callee;
        }
    }
    

    在这里,我们创建一个新的包装器对象(并且不向数组本身添加属性)。包装器对象仍然可以访问数组的所有属性。不过有一个小问题:

    var foo = wrap([1,2,3]);
    document.writeln(foo.length); // writes 3
    foo.push(4);
    document.writeln(foo.length); // writes 4 in FF, 3 in IE
    foo[4] = 5;
    foo[5] = 6;
    document.writeln(foo.length); // still writes 4?!
    

    使用 foo[4] = 将访问我们的包装器对象和属性 4 5 push() 将无法正确更新阵列。。。

    如果您的包装器对象不需要“重新路由”对数组对象的调用,那么还有其他使用闭包的解决方案——sktrdie的第一个示例就是其中之一。我反对它们,因为它们也会在每次调用中创建新的函数对象。我要做的是:

    function wrap(array) {
        if(this instanceof arguments.callee)
            this.array = array;
        else return new arguments.callee(array);
    }
    
    wrap.prototype.doSomething = function() {};
    wrap.prototype.doOther = function() {};
    

    在这里,您可以在中访问阵列 doSomething() 杜瑟() this.array .

        6
  •  0
  •   geowa4    16 年前

    只需扩展数组对象,并向对象添加您喜欢的方法。然后,您可以创建一个桥接函数,该函数将数组作为参数,并返回您的数组版本。这种方法更简单、更有用。