Search code examples
jqueryextend

jQuery extend - target object don't get extended


var collection = $('ul li');
collection.each(function (index) {
    var test = $.extend($(this), {
    // var test = $.extend(collection.eq(index), {
        someProperty: 'val'
    });
    console.log(test.someProperty);
});
console.log(collection.eq(0).someProperty);

And the test: http://jsfiddle.net/simo/G3yCr/1/

I'm trying to extend each object inside a jquery collection. I want to access the properties directly from each item inside the collection.

The question is why the collection.eq(index) object don't get extended. The commented line is alternative and gives the same results.

The spec: http://api.jquery.com/jQuery.extend/


Solution

  • In your .each function this is referring to the individual DOM elements from the collection, and not to a jQuery object.

    When you then call $(this) you're creating a new jQuery object, it's not the one from the collection.

    The easiest way to make this additional property persist would be to add it to the element itself. Alternatively use .data() to store and retrieve the additional properties.

    On ES5 browsers you can then use a (possibly nasty) hack to make your .data() look like a real property:

    (function($) {
        Object.defineProperty($.fn, 'foo', {
            get: function() {
                return $(this).data('foo');
            },
            set: function(v) {
                $(this).data('foo', v);
            }
        });
    })(jQuery);
    
    $('#d1').foo = 'bar';
    $('#d2').foo = 'wot';
    
    alert([$('#d1').foo, $('#d2').foo]);
    

    Note that (AFAIK) no other jQuery code adds properties (other than .length) on a jQuery object. Use of this trick may confuse other developers.