Reputation: 31983
In my program I have added the Array.prototype.equals() function listed in this SO post.
I have the following function to perform deep-copies of arrays (I am using this strictly for logging purposes - so that I can see what my arrays look like at various points in time in the Chrome console.)
function deepCopy(array) {
return $.extend(true, [], array);
}
I then use this as such:
console.log("Sorting metrics list by metric name...");
console.log("Metrics list before sort:");
console.log(deepCopy(metrics));
metrics.sort(compare);
console.log("Metrics list after sort:");
console.log(deepCopy(metrics));
For reference, my compare function is:
function compare(a, b) {
return a.name.localeCompare(b.name);
}
When I view my metrics array in the Chrome console after the deepCopy(), the equals method defined for the Array.prototype is IN the array! Picture:
As you can see from the screen shot, I check the actual value of the metrics array after everything has run, and it clearly does not contain the equals method. This is my reasoning for believing it has something to do with how jQuery().extend handles copying arrays.
Any ideas on how to fix my deepCopy function to stop this? (Or change my prototype function, if needed.)
Upvotes: 0
Views: 1385
Reputation: 115950
Two issues here:
console.log
is different from expression evaluation$.extends
loops over all enumerable properties of the source object and adds them as own instance properties (not inherited properties) of the target object. If you make your prototype property non-enumerable, it won't be copied directly onto the target:
Object.defineProperty(Array.prototype, "equals", {
enumerable: false,
value: function(array) { /* ... */ }
});
(See some helpful reading: Don’t modify objects you don’t own.)
Your final test where you type metrics
into the console doesn't show you the equals
property, but it's actually still there. Consider the following console session in Chrome, where we add an enumerable property on the Array prototype and then use an array with $.extends
:
> Array.prototype.foo = "egg";
"egg"
> $.extend(true, [], ['bar', 'baz'])
["bar", "baz"]
> console.log($.extend(true, [], ['bar', 'baz']))
["bar", "baz", foo: "egg"]
> Object.getOwnPropertyNames( $.extend(true, [], ['bar', 'baz']) )
["0", "1", "length", "foo"]
The non-index properties only show up when we explictly use console.log
; they don't show up when we just evaluate the expression, even though getOwnPropertyNames
confirms they're there.
Upvotes: 2