jQuery如何返回所选元素的数组

3
我刚刚看了John Resig的谷歌技术演讲,他说jQuery作为一个数组运作。听从这个建议后,我尝试使用一个子类化的数组,并且效果很棒,但是我查看了jQuery源代码,并��有看到他们使用相同的方法: jQuery.prototype = new Array(); 甚至在`window.$`对象的原型链中,也没有调用`Array.prototype.methods`的原生方法,所以我想知道jQuery对象如何返回所选元素的数组。
我尝试使用普通对象,但如果返回一个数组,就会停止链接命令的能力。如果有可能从`Array.prototype`中获取一些方法,则什么是返回一个数组必要的?
这是我正在尝试的内容。
;(function(window, document, undefined){

    function MyLib(){};

    // prototype constructor functions
    function Core(){};
    function Methods(){};

    // create new instance of the MyLib object and call the construct method
    function myLib(selector){
        return new MyLib().construct(selector);
    }
    // allow adding new methods to the prototype from the window. 
    // eg $.extend('module', 'name', 'function')
    myLib.extend = function(module, name, fn){
        if(typeof fn === 'function'){
            if(!MyLib.prototype[module][name]){
                MyLib.prototype[module][name] = fn;
            }
        } else if(typeof fn === 'object'){
            for(var key in fn){
                if(!MyLib.prototype[module][key]){
                    MyLib.prototype[module][key] = fn[key];
                }
            }
        } else {
            throw new Error("invalid type, function or objects are required");
        }
    }

    MyLib.prototype = new Array();
    MyLib.prototype.core = new Core();
    MyLib.prototype.methods = new Methods();

    MyLib.prototype.construct = function(selector){
            var elems = document.getElementsByTagName(selector);
            Array.prototype.push.apply(this, Array.prototype.slice.call(elems, 0, elems.length));
            return this;
        };

    // access to prototype objects with $.core && $.methods
    myLib.core = MyLib.prototype.core;
    myLib.methods = MyLib.prototype.methods;

    // give the window access to the constructor function
    window.$ = myLib;
    // give the window access to the prototype object for debugging
    window.$$ = MyLib;

})(window, document);

// this adds a new method to the methods object within the prototype
$.extend('methods', 'test', function(){alert('method successfully added')});

// the added method can be accessed with
$.methods.test();
// or
$('tagName').test();

感谢任何回答。

1
那绝对不是jQuery的做法。jQuery在jquery原型上定义了特定的Array方法,但并非全部。在jQuery中发生的一切都是给一个对象赋予了长度和类似数组的属性,以及一些Array方法。 - Kevin B
1个回答

4

要像数组一样工作(通常我们称之为“类似数组”的对象),您不需要从Array继承,只需

  • 具有名为length的相关属性
  • 具有属性"0""1"... length-1(您可以跳过其中一些)

例如:

var a = {
  length: 2,
  "0": 'first',
  "1": 'second'
}
var b = [].slice.call(a); // yes, Array functions work !
console.log(b); // logs ["first", "second"] 

当然,您可以通过定义基于原型的类和相关的原型函数(就像 jQuery 所做的那样)来为 lib 用户简化所有这些操作:

var A = function(){
  this.length = 2;
  this['0'] = 'first';
  this['1'] = 'second';
}
A.prototype.slice = [].slice;
A.prototype.splice = [].splice;
var a = new A, b = a.slice();
console.log(a); // logs ["first", "second"] because of the splice function
console.log(Array.isArray(a));
console.log(b); // logs ["first", "second"] because it's really an array
console.log(Array.isArray(b)); // true

如果您希望将对象记录为数组,则需要使用splice函数。


我确实设置了一个这样做的程序,但它没有返回一个数组对象,而是总是返回类似数组对象的最后一个元素。 - synthet1c
2
@synthet1c,我不理解你的评论。 - Denys Séguret
当调用构造方法时,我使用了一个指定长度属性的构造函数。因为我返回了this,它返回了类似数组的对象,但是它只显示了返回时其中的最后一个元素。这并不是什么大问题,因为我正在使用的东西是有效的,并且在我使用类似数组的对象时也有效,我只是想知道为什么jquery将一个数组返回到控制台。 - synthet1c
2
@synthet1c 如果要将您的对象记录为数组,则需要具有“splice”函数。 - Denys Séguret
我找到了问题,是当我调用本地push方法时它会返回最后一个元素,所以我将只需要编写一个方法来添加到对象中。谢谢你的帮助dystroy。 - synthet1c

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接