2

I was trying out the jQuery Data linking proposal from Microsoft and noticed something strange.

My objects get this extra property and I was wondering what the reason for that is. I first thought it was a mistake I made but I noticed their demo page does the same thing

This is the json result of my objects:

[{
        "propertyName":"ProductNamese",
        "controlType":"Text",
        "jQuery1274021322131":6
    },
    {
        "propertyName":"Price",
        "controlType":"Number",
        "jQuery1274021322131":9
    },
    {
        "propertyName":"Description",
        "controlType":"TextArea",
        "jQuery1274021322131":12
    }
]

The property I am talking about is "jQuery1274021322131".

Anurag
  • 140,337
  • 36
  • 221
  • 257
Pickels
  • 33,902
  • 26
  • 118
  • 178
  • How is this JSON-result constructed? Then it would be easier for us to check out the source code of this jQuery plugin – Harmen May 16 '10 at 15:08

2 Answers2

4

When you cast an DOM object to a jQuery object (i.e. $("#SomeElementID")), jQuery appends a special "expando" property to the object. I believe that this property is used internally by the library to assist in caching the element in its internal array for faster access.

Digging through the library, this is the code that creates that value and how it's used internally:

    var expando = "jQuery" + now(), uuid = 0, windowData = {};

    jQuery.extend({
        cache: {},

        data: function( elem, name, data ) {
            elem = elem == window ?
                windowData :
                elem;

            var id = elem[ expando ];

            // Compute a unique ID for the element
            if ( !id )
                id = elem[ expando ] = ++uuid;

            // Only generate the data cache if we're
            // trying to access or manipulate it
            if ( name && !jQuery.cache[ id ] )
                jQuery.cache[ id ] = {};

            // Prevent overriding the named cache with undefined values
            if ( data !== undefined )
                jQuery.cache[ id ][ name ] = data;

            // Return the named cache data, or the ID for the element
            return name ?
                jQuery.cache[ id ][ name ] :
                id;
        },
// snipped
BradBrening
  • 5,418
  • 25
  • 30
1

jQuery uses the expando to associate an object (dom element, or otherwise) with it's cache of data when using the data() method (it is NOT caused by simply running $() on it, as the accepted answer specifies). The data linking plugin uses data() on the object, thus creating the expando. It's unfortunate that the expando is so 'regular' -- it should be more easily hidden. For example, it should be encapulated a function so that JSON serializers don't include it. jQuery works with regular objects, but there are some rough edges like this one. Hopefully they can be ironed out in the future.

InfinitiesLoop
  • 14,349
  • 3
  • 31
  • 34
  • The reason it's a plain string is to avoid attaching functions to DOM elements. Using a plain string as a key into the $.data cache means that you don't get memory leaks in IE. – Sean McMillan May 04 '11 at 15:52
  • Attaching a function to a DOM element is not itself a leak, it's only a leak if that function references the element (directly or via closure reference) as that causes a circular reference between DOM and JS objects that must be broken to avoid leaking. You want to avoid putting the data directly on the element as well, since who knows what the data contains, it might cause a circular reference as well. What I proposed was an empty function that contains the expando (the 'string'), or even, has the expando as a field (on the function). It's safe. Just a trick to hide it from JSON serializers. – InfinitiesLoop May 04 '11 at 23:21