【问题标题】:How does jQuery allow you to use [] on a jQuery object?jQuery 如何允许您在 jQuery 对象上使用 []?
【发布时间】:2011-02-11 18:00:58
【问题描述】:

假设我有以下标记:

<div></div>
<div></div>
<div></div>

我使用以下方法来检索它们:

var divs = $('div');

我怎么可能通过使用[] 语法检索相应的DOM 元素并且 还可以调用jQuery 对象上的方法,例如.first()? p>

var div_one = divs[0];

我问这个问题是因为在我看来 divs 是一个 jQuery 对象,而不是真正的 JavaScript Array 对象。

这是如何工作的?

【问题讨论】:

  • 对不起,我写到这里,我不知道如何向其他用户发送消息。你为什么删除了我昨天问题的答案?这是我需要做的事情的轨道
  • @TheDisintegrator 如你所愿取消删除。

标签: javascript jquery


【解决方案1】:

数字索引只是返回对象的属性。类似于这样做:

var obj = {};
obj[0] = 'foo';
alert(obj[0]);

数组和伪数组对象几乎相同 - 唯一的区别是真正数组的length 属性由 JavaScript 引擎自动管理。

【讨论】:

  • @Nathan:不,它没有。它返回一个对象,其中包含一些 Array 方法的原型。它不是一个数组。
  • @Nathan 如果我可以调用.eq().first() 之类的方法,它怎么可能是Array
  • @patrickdw:我不知道这个。我现在要再看看来源。谢谢你纠正我。
  • @patrickdw 我在 jQuery IRC 频道中与团队进行了交谈,他们为我解决了问题。对 jQuery() 的调用会返回一个 jQuery 对象,该对象已动态应用了索引器属性。当属性被调用时,它们返回对 jQuery().get() 的调用,该调用返回包含在 jQuery 对象中的 DOM 元素数组。就像你说的,jQuery 对象上的所有 Array 方法都只是简单地在其上进行原型化,并对 DOM 元素的内部数组进行操作。
  • @Nathan:我听到你在说什么,但我个人不喜欢像 "array...contained in the jQuery object"“内部数组”。这意味着 jQuery 对象具有对实际数组的内部引用。 What it actually doesget() 被调用时,它是否通过Array.prototype.slice 构造一个新的(实际的)数组。只要属性是数字的,您就可以对常规对象执行此操作,并且它也具有length 属性。 Example.
【解决方案2】:

您可以对任何对象执行此操作。它实际上与它是一个“类似数组”的对象没有任何关系。

var myObj = {};

myObj[0] = 'some value';

alert( myObj[0] );

这是一个创建类数组对象的示例:

示例: http://jsfiddle.net/8rgRM/

  // create constructor
function MyObj(){}

  // extend it with an Array method
MyObj.prototype.push = Array.prototype.push;

  // create an instance
var inst = new MyObj;

  // use the push method
inst.push( 'some value' );

  // the instance automatically has a length property that was updated
alert( inst.length );

长度属性的行为可能与实际数组中的行为相同,但事实并非如此。

例如,对于一个数组,您可以使用length = 0 来清除数组的内容,但它不适用于上述对象。

在 jQuery 的源代码中,here is where Array.prototype.push 被引用,here is where it is extended 被引用到 jQuery 原型中。

【讨论】:

    【解决方案3】:

    这会澄清一些事情。试试看吧。

    //used to produce pure classical inheritance
    function clone(obj){
        function F(){};
        F.prototype=obj;
        return new F();
    }
    // Constructor function, used to instantiate a new object of myDivQuery Class
    myDivQuery = function (){
        var div_list = document.getElementsByTagName('div');
        for (var i=0; i < div_list.length; i++){
            this[i] = div_list[i];
        }
        this.length = div_list.length;
    };
    //myDivQuery inherits from Array class
    myDivQuery.prototype = clone( new Array );
    //add new methods to myDivQuery class, which is not added to the orginal Array class
    myDivQuery.prototype.first = function (){
        return this[0];
    }
    
    myDivQuery.prototype.last = function (){
        return this[this.length - 1]
    }
    divs = new myDivQuery();
    divs[0]; // first div on the page;
    divs[1]; // the second div on the page ....
    divs instanceof Array; //true
    divs instanceof myDivQuery; //true
    divs.first() === divs[0]; //true
    divs.last(); //last div on page
    Array.prototype.first; //undefined
    divs.slice(1); //but still can use array methods
    divs.reverse(); //another array method
    

    这就是你创建伪数组的方式,一个重要的说明是javascript中的数组不能被子类化,即不能创建具有相同数组特征的子数组,主要原因是数组中的长度属性,对 JS 程序员是隐藏的,但是有很多技巧和变通方法可以做到这一点,要了解更多信息,请阅读 kangax 的这篇精彩文章。 http://perfectionkills.com/how-ecmascript-5-still-does-not-allow-to-subclass-an-array/

    【讨论】:

      【解决方案4】:

      在 JavaScript 中,您可以使用与数组索引表示法相同的语法访问对象的属性:

      var o = {'foo':'bar'},
        fooVar = 'bar';
      
      //these all alert 'bar'
      alert(o.foo);
      alert(o['foo']);
      alert(o[fooVar]);
      

      但是,您只能对有效名称使用点表示法。 o[0] 有效,但 o.0 无效。

      jQuery 返回一个jQuery.init 对象,其中包含许多属性(即length),以及dom elements 或选择器匹配的其他原始javascript 对象的映射,从0 到@ 987654328@.

      【讨论】:

        【解决方案5】:

        选择器的结果(开始帖子中的$("div"))返回结果with the type Jquery

        引用 jquery 页面:

        jQuery 对象本身的行为很多 像一个数组;它有一个长度 属性和元素 对象可以被他们的访问 数字索引 [0] 到 [length-1]。 请注意,jQuery 对象不是 实际上是一个 Javascript Array 对象,所以 它没有 a 的所有方法 true 数组对象,例如 join()。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-03-19
          • 1970-01-01
          • 1970-01-01
          • 2011-04-12
          • 2016-12-24
          • 2011-04-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多