【问题标题】:JQuery Functions that Return the Same Object返回相同对象的 JQuery 函数
【发布时间】:2022-01-13 20:43:59
【问题描述】:

有许多 JQuery 函数似乎只是返回对相同对象的引用,只是为了促进调用链。但是在处理特定实例很重要的事情时,我注意到如果我测试对象是否相等,则返回的对象不是同一个对象。但是,它们反映了相同的信息。

从 .css() 返回的对象有什么“不同”?为什么他们不只是修改实例并返回相同的实例,是否有设计原因?

在控制台中我可以这样做,并且两个实例都反映了对第二个实例所做的更新颜色,但是如果对象是同一个对象,则测试 == 返回 false。

var blah = $('#div1');
var blah2 = $('#div1').css('color','red');

blah.css('color'); -- 'rgb(255, 0, 0)'
blah2.css('color'); -- 'rgb(255, 0, 0)'

blah === blah2
false

blah == blah2
false

我想澄清一下,我理解值比较和对象比较之间的区别。我知道测试表明它们是两个单独的对象。这并没有让我感到困惑,它只是让我感到惊讶。他们可以轻松地维护同一个对象,通过它们的句柄修改元素,并返回同一个对象而无需创建新对象。

通常,您会看到带有对象调用链的两种模式之一。每次调用都返回相同的对象引用,保持相同的引用并简单地修改该对象的属性/子对象。或者每次调用都会创建一个新对象,修改并返回该新对象而不修改原始对象。

如果您想遵循不可变的模式,那么第二种方法是有利的,这样每次调用都会生成一个新对象而不修改先前的实例。

在这种情况下,两个对象都引用相同的 HTML 元素并反映相同的信息,所以令我惊讶的是 JQuery 正在创建并返回一个新对象。我认为这是一个明确的设计选择,只是对我来说并不明显。

【问题讨论】:

  • 您正在通过使用选择器调用 $ 创建一个新实例。如果你会做var blah2 = blah.css('color','red');,那么blah === blah2 将是真的。
  • @Teemu Dang 我不知道我是怎么错过的。
  • 不可能两次“创建”同一个对象。

标签: javascript jquery


【解决方案1】:

blah 永远不会等于blah2,它们是两个独立的 jQuery 对象(尽管 ID 相同)。

您可能想要比较 css('color') 的结果,它会正确返回值的字符串表示形式:

var blah = $('#div1');
var blah2 = $('#div1').css('color','red');

console.log(blah.css('color') == blah2.css('color'));
console.log(blah.css('color') === blah2.css('color'));
#div1 {
  color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="div1"></div>

【讨论】:

    【解决方案2】:

    相等差异与对象的存储和引用方式有关。每次创建一个新对象时,都会为它分配一个内存位置。因此,当您访问该对象时,您的代码将检查该内存位置并在那里检索该对象。问题是您的两个对象保存在内存中的不同位置。因此,当您检查它们是否相等时,代码会看到内存中的两个位置不同。因此,由于位置不同,它返回 false。虽然内容完全一样,但实际上是在比较内存中的位置。

    希望这会有所帮助,如果我能澄清任何事情,请告诉我。

    【讨论】:

      【解决方案3】:

      每次使用$('myelement') 查询元素时,jquery 都会返回一个对象,其中包含有关该元素的大量数据。但是,当在两个对象中使用相等运算符===== 时,js 会与对象的引用而不是值进行比较。也就是说,虽然js中的两个对象的值相同,但是如果它们的引用不同,它们之间的比较可能是false

      让我们看一些例子:

      const a = {
        foo: 1
      };
      
      const b = {
        foo: 1
      }
      
      const c = b;
      
      // returns false, same value but different reference
      console.log(a == b);
      // returns true, same value and same reference
      console.log(b == c);
      // returns false, same value but different reference
      console.log(a == { foo: 1 });

      这意味着虽然 2 个对象可能具有相同的值,但如果它们没有相同的引用,js 会使用 ===== 运算符将它们评估为 false

      您可以在这个 jquery 示例中查看它:

      const foo1 = $('#foo');
      const foo2 = $('#foo');
      
      console.log(foo1 == foo2);
      console.log(foo1 === foo2);
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
      
      <div id="foo">Hello world</div>

      那么我们该如何解决呢?

      幸运的是,Jquery 有自己对真实 HTML 元素的引用,使用 [0] 索引:

      const foo = $("#foo");
      
      console.log(foo[0])
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
      
      <div id="foo">Hello world</div>

      因此,您可以在 HTML 元素之间进行比较,它们在使用相等运算符时具有不同的行为:

      const foo1 = $('#foo');
      const foo2 = $('#foo');
      
      console.log(foo1[0] == foo2[0]);
      console.log(foo1[0] === foo2[0]);
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
      
      <div id="foo">Hello world</div>

      【讨论】:

        【解决方案4】:

        正如 Teemu 所指出的,我在两次使用 $ 选择器时出错,我当然希望它生成一个新的 JQuery 类型,因为它会生成一个新的 HTMLElement 集合。所以我的测试无效,因为css 没有生成新对象,$ 生成了。我不知道我是怎么错过的。

        一旦我对此进行了调整,.css( 确实返回了与我预期相同的对象。所以这并不奇怪,我的测试根本无效。

        var blahA = $('#div1');
        var blahB = blahA.css('color','red');
        blahA == blahB
        true
        

        【讨论】:

          猜你喜欢
          • 2017-07-17
          • 2019-02-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-08-02
          • 1970-01-01
          相关资源
          最近更新 更多