how does jquery return an array of the selected elements

泪湿孤枕 提交于 2019-12-07 13:46:41

问题


I have just seen a google tech talk presented by John Resig where he said jQuery operates as an array. Following that advice I have been playing with a subclassed array and it works great but I have been looking through the jQuery source and can't see that they have used the same method of

jQuery.prototype = new Array();

And I can't see it even taking the native Array.prototype.methods with call/apply or in the prototype chain in the window.$ object, so I am wondering how does the jQuery object return an array of the selected elements.

I have tried using an ordinary object, but if returning an array it stops the ability to chain commands

If it is possible to take some methods from Array.prototype what is essential to return an array?

This is what I was playing with.

;(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();

thanks for any answers


回答1:


To work "as an array" (we usually speak of "array-like" object) you don't inherit from Array, you simply have to

  • have a relevant property named length
  • have properties "0", "1"... length-1 (you might skip some)

Example :

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

Of course you can make all this easier for the lib users by defining a prototype based class and the relevant prototype functions (just as jQuery does) :

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

If you want your objects to be logged as arrays, you need to have the splice function.



来源:https://stackoverflow.com/questions/21706106/how-does-jquery-return-an-array-of-the-selected-elements

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!