I tried to prototype a length() method to Object and broke jQuery – how?

后端 未结 2 755
灰色年华
灰色年华 2021-01-19 06:55

I wrote the following:

Object.prototype.length = function(){
    var count = -1;
    for(var i in this) count++;
    return count;
}

It wor

2条回答
  •  無奈伤痛
    2021-01-19 07:17

    That prototype extension is breaking the $.each method, because this method detects between arrays and objects using the length property (in jQuery 1.4.2):

    // core.js Line 533
    each: function( object, callback, args ) {
        var name, i = 0,
            length = object.length, // <--- your function from Object.prototype
            isObj = length === undefined || jQuery.isFunction(object);
    //...
    

    As you can see, the isObj variable will be true only if it doesn't contains a length property (or the property value is undefined).

    If isObj is false, jQuery will try to iterate using a normal for loop:

    for ( var value = object[0];
        i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
    

    Then, the appendTo method is created using $.each, that's why is not defined:

    //...
    jQuery.each({
        appendTo: "append",
        prependTo: "prepend",
        insertBefore: "before",
        insertAfter: "after",
        replaceAll: "replaceWith"
    },
    //...
    

    I will always recommend to stay away from extending Object.prototype, when you extend this prototype ALL objects receive those additional properties.

    This is especially problematic since when you iterate over the properties of the object these new properties appear, causing all sorts of unexpected behavior.

提交回复
热议问题