jQueryにおけるif(currentObject === lastObject)とif(currentObject.get(0) === lastObject.get(0))の違い


jQueryで、

currentObjectとlastObjectがそれぞれひとつのjQueryオブジェクトである場合、  
ふたつが同一のものであるか比較する時に、

[code]

    if(currentObject === lastObject) {
    　//処理
    }
    
[/code]

とせずに、

[code]

    if(currentObject.get(0) === lastObject.get(0)) {
    　//処理
    }
    
[/code]

としなければいけないのは、どのような時ですか？

または、ふたつにはどのような違いがありますか？




> currentObjectとlastObjectがそれぞれひとつのjQueryオブジェクトである場合、  
>  ふたつが **同一** のものであるか比較する

「同一」の定義によります。

## javascriptにおける任意のObjectの比較

[Comparison operators](https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators)より、

> If both operands are objects, then JavaScript compares internal references
> which are not equal when operands refer to different objects in memory.

意訳すれば参照型オブジェクトを比較する場合、それが同一であるとはふたつのオブジェクトの参照先が等しいことを意味します。すなわち、

[code]

    // 見た目が同じでも参照先が異なるならばfalse
    console.assert({} !== {});
    console.assert({ value: 1 } !== { value: 1 });
    
    // 参照先が等しい場合にtrue
    const a = {};
    const b = a;
    console.assert(a === b);
    
[/code]

です。

## jQueryオブジェクトの比較

jQueryオブジェクトが前述した「jsにおけるオブジェクトの同一性」を満たすかを確認するとき、オブジェクトを直接比較します。

[code]

    console.assert(jQuery(window) !== jQuery(window));
    
    const $window = jQuery(window);
    const currentObject = $window;
    const lastObject = $window;
    console.assert(currentObject === lastObject);
    
[/code]

対して、jQueryオブジェクトが「 **同一のDOMオブジェクトを含んでいる**
」ことを同一と定義するならば、一般的にはjQueryのAPIである[.is()](http://api.jquery.com/is/)を使用します。

[code]

    console.assert(jQuery(window).is(jQuery(window)));
    
[/code]

これはjQueryオブジェクトが単一のDOMオブジェクトを参照している場合に限り、質問にある後者の比較表現と等価な処理になります。

[code]

    console.assert(jQuery(window).get(0) === jQuery(window).get(0));
    
[/code]

また、必要な場面があるかは不明ですが「 **含まれているDOMオブジェクトが完全に一致する**
」ことと定義するならば、標準ではこのような機能をもつAPIが無さそうですので、自前でjQueryオブジェクトに含まれるDOMオブジェクトを全数比較する必要がありそうです。こちらはあまり検証していないので参考までに。

[code]

    // 拡張API jQuery().equals(jQueryObject)
    jQuery.fn.equals = function (obj) {
        if (!(obj instanceof jQuery) || this.length !== obj.length) {
            return false;
        }
        // 順序無視での比較
        for (let i = 0; i < this.length; i++) {
            if (obj.index(this.get(i)) === -1) {
                return false;
            }
        }
        return true;
    };
    
    //
    console.assert(jQuery('div').equals(jQuery('div')));
    console.assert(!jQuery('div:first-child').equals(jQuery('div')));
    console.assert(!jQuery('div').equals(jQuery('div:first-child')));
    
[/code]

ご質問の意図と異なる回答であればコメントでお知らせください。




> currentObjectとlastObjectがそれぞれひとつのjQueryオブジェクトである場合、  
>  ふたつが **同一** のものであるか比較する

「同一」の定義によります。

## javascriptにおける任意のObjectの比較

[Comparison operators](https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators)より、

> If both operands are objects, then JavaScript compares internal references
> which are not equal when operands refer to different objects in memory.

意訳すれば参照型オブジェクトを比較する場合、それが同一であるとはふたつのオブジェクトの参照先が等しいことを意味します。すなわち、

[code]

    // 見た目が同じでも参照先が異なるならばfalse
    console.assert({} !== {});
    console.assert({ value: 1 } !== { value: 1 });
    
    // 参照先が等しい場合にtrue
    const a = {};
    const b = a;
    console.assert(a === b);
    
[/code]

です。

## jQueryオブジェクトの比較

jQueryオブジェクトが前述した「jsにおけるオブジェクトの同一性」を満たすかを確認するとき、オブジェクトを直接比較します。

[code]

    console.assert(jQuery(window) !== jQuery(window));
    
    const $window = jQuery(window);
    const currentObject = $window;
    const lastObject = $window;
    console.assert(currentObject === lastObject);
    
[/code]

対して、jQueryオブジェクトが「 **同一のDOMオブジェクトを含んでいる**
」ことを同一と定義するならば、一般的にはjQueryのAPIである[.is()](http://api.jquery.com/is/)を使用します。

[code]

    console.assert(jQuery(window).is(jQuery(window)));
    
[/code]

これはjQueryオブジェクトが単一のDOMオブジェクトを参照している場合に限り、質問にある後者の比較表現と等価な処理になります。

[code]

    console.assert(jQuery(window).get(0) === jQuery(window).get(0));
    
[/code]

また、必要な場面があるかは不明ですが「 **含まれているDOMオブジェクトが完全に一致する**
」ことと定義するならば、標準ではこのような機能をもつAPIが無さそうですので、自前でjQueryオブジェクトに含まれるDOMオブジェクトを全数比較する必要がありそうです。こちらはあまり検証していないので参考までに。

[code]

    // 拡張API jQuery().equals(jQueryObject)
    jQuery.fn.equals = function (obj) {
        if (!(obj instanceof jQuery) || this.length !== obj.length) {
            return false;
        }
        // 順序無視での比較
        for (let i = 0; i < this.length; i++) {
            if (obj.index(this.get(i)) === -1) {
                return false;
            }
        }
        return true;
    };
    
    //
    console.assert(jQuery('div').equals(jQuery('div')));
    console.assert(!jQuery('div:first-child').equals(jQuery('div')));
    console.assert(!jQuery('div').equals(jQuery('div:first-child')));
    
[/code]

ご質問の意図と異なる回答であればコメントでお知らせください。

