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

jquery web前端开发 前端 JavaScript

Medea 10 years, 4 months ago

其实看源码很简单就能知道了,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")) 也能达到类似的效果。

江汉热线线长 answered 10 years, 4 months ago

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


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

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

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

☆羽星飞鹄☆ answered 10 years, 4 months ago

Your Answer