Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What changed in jQuery 1.9.1 to cause the .data extension method to return null instead of undefined when a selector returns no results?

Recently the application I work on upgraded from jQuery 1.7.1 to 1.10.2 with Migrate 1.2.1 included.

After upgrading we noticed that jQuery returned different results for the extension method data depending on if the selector had any results. The attr extension method always returns undefined regardless of the selector results.

Using the following HTML document I ran tests with versions 1.7.1, 1.8.3, 1.9.1, and 1.10.2.

<html>
<head></head>
<body>

    <div id="results">trying to access .data member off a selector that returns no results</div>

    <script type="text/javascript" src="jQuery.js"></script>
    <script type="text/javascript">
        $(function(){
            var target = $("#results");
            target.append("<div>jQuery " + $.fn.jquery + " => " + $("p").data("blah") + "</div>");
            target.append("<div>jQuery " + $.fn.jquery + " => " + $("p").attr("data-blah") + "</div>");

            target.append("<div>jQuery " + $.fn.jquery + " => " + $("body").data("blah") + "</div>");
            target.append("<div>jQuery " + $.fn.jquery + " => " + $("body").attr("data-blah") + "</div>");
        });
    </script>
</body>

In 1.7.1 and 1.8.3 all results are undefined. In 1.9.1 and 1.10.2 results for an empty selector with .data("blah") switched from undefined to null.

I've reviewed the 1.9.0 upgrade documents as well as the 1.10.0 release notes and haven't found any indication of these changes. Does anyone know why this is? Was it intentional?

I have included a fiddle to show how the various versions of jQuery have handled this.

http://jsfiddle.net/T5L6Y/6/

like image 754
Sam R Avatar asked Jan 24 '14 21:01

Sam R


1 Answers

This change of behavior was not wanted, it is (or rather: it was) a bug. The difference comes from these lines:

In jquery-1.8.3.js:1772

if (value === undefined) {
    data = this.triggerHandler("getData" + part, [parts[0]]);

    // Try to fetch any internally stored data first
    if (data === undefined && elem) {
        data = jQuery.data(elem, key);
        data = dataAttr(elem, key, data);
    }

    return data === undefined && parts[1] ? 
    this.data(parts[0]) : 
    data;
}

When the selector is empty, data is returned and at this point data is undefined.

But in jquery-1.9.1.js:1824

if (value === undefined) {
    // Try to fetch any internally stored data first
    return elem ? dataAttr(elem, key, jQuery.data(elem, key)) : null;
}

When the selector is empty, elem is evaluated to false and null is returned. This was not intended and was actually fixed by this commit applied in November. Running the code with jquery-1.11.0 has the original behavior: undefined is returned.

like image 193
Djizeus Avatar answered Nov 15 '22 14:11

Djizeus