首页 > jQuery对象用console.log输出看到的很像数组是怎么实现的?

jQuery对象用console.log输出看到的很像数组是怎么实现的?

图片上传不了,老出错;就只能复制啦!

这个是我自己构造的对象,用console.log输出看到是这样;
foo.fn.foo.init {0: div, 1: div, 2: div, 3: div, 4: div, selector: "div", init: function, aouth: "jer", age: 24, add: "江西"…}

jquery对象用console.log输出像一个数组;
[div, div, div, div, div, prevObject: b.fn.b.init[1], context: document, selector: "div", jquery: "1.9.1", constructor: function…]

想知道它是怎么实现的,下面是我写的源码;

(function(){
    function foo(selector){
        return new foo.prototype.init(selector);
    };
    foo.fn = foo.prototype= {
        init : function(selector){
            var elems = document.getElementsByTagName(selector),
            len = elems.length,
            i = 0;
            for(;i < len;i++){
                this[i] = elems[i];
            };

            this.selector = selector
                return this;
        },
        aouth:'jer',
        age: 24,
        add :'江西'
    };
    foo.prototype.init.prototype = foo.prototype;
    foo.fn.sayName = function(){
        return this;
    };
    foo.fn.sayAdd = function(){
        return this;
    };
    window.foo = foo;
})();
//console.log(foo);
var selects = foo('div');
console.log(selects);

这个其实不难,典型的 Ducking Type 应用。一个 Javascript 对象,只要定义了 length 属性和 splice 方法,它看起来就像一个数组。例如:

var x = {
  '0': 'foo',
  '1': 'bar',
  length: 2,
  splice: function () {}
};

console.log(x);  // ["foo", "bar", splice: function]

只要它会呱呱叫,走路一摇一摆,它就是个鸭子……


其实看源码很简单就能知道了,jQuery并没有做的很复杂,只是仅仅的把创建个数组把对象的每个属性放进去而已。下面说说我的发现过程:

  1. 首先在控制台中打印$,发现其调用了Q.fn.init函数。

    console.log($);
    //function (t,e){return new Q.fn.init(t,e)} 
    
  2. 上源码去查找init部分的实现,查看源码我们可以发现jQuery在初始化函数最后使用了jQuery.makeArray函数对对象进行了处理。OK,看到这个名字我觉得答案已经离我们很近了。
  3. 搜索源码查找makeArray的实现,OK,我找到了,在这里。函数的最后是调用了jQuery.merge函数把对象添加到了this中。
  4. 我们继续查找jQuery.merge函数的实现,嗯,在同一个文件中。这个函数就非常明显的告诉我们是一个遍历添加的过程。

我觉得jQuery这么写估计是为了兼容,其实直接用[].slice.call(document.querySelectorAll("div"))也能达到类似的效果。

【热门文章】
【热门文章】