PDA

View Full Version : [FIXED] [4.1.3] Ext.clone adds enumerables to simple object in old IEs



westy
22 Nov 2013, 2:57 AM
Ext version tested:

Ext 4.1.3
Browser versions tested against:

IE8
DOCTYPE tested against:

default
Description:

Ext.clone copies enumerables from the object being cloned even if they are inherited from a base class.
Steps to reproduce the problem:

Create a simple object, var obj = { prop: 1 }, say.
Test obj.hasOwnProperty('constructor') - will return false.
Clone the object.
Test obj.hasOwnProperty('constructor').
The result that was expected:

The object should not have a constructor.
The result that occurs instead:

The object has a constructor, and the other enumerables.
Fiddle:

Run this in IE8 - https://fiddle.sencha.com/fiddle/1o8/preview
Suggested fix:


clone: function(item) {
var type,
i,
j,
k,
clone,
key;

if (item === null || item === undefined) {
return item;
}

// DOM nodes
// TODO proxy this to Ext.Element.clone to handle automatic id attribute changing
// recursively
if (item.nodeType && item.cloneNode) {
return item.cloneNode(true);
}

type = toString.call(item);

// Date
if (type === '[object Date]') {
return new Date(item.getTime());
}

// Array
if (type === '[object Array]') {
i = item.length;
clone = [];
while (i--) {
clone[i] = Ext.clone(item[i]);
}
}
// Object
else if (type === '[object Object]' && item.constructor === Object) {
clone = {};

for (key in item) {
clone[key] = Ext.clone(item[key]);
}

if (enumerables) {
for (j = enumerables.length; j--;) {
k = enumerables[j];
// <WestyFix>
if (item.hasOwnProperty(k)) {
clone[k] = item[k];
}
// </WestyFix>
}
}
}

return clone || item;
}




Was wondering why we sometimes see hanging (or stack overflows) in old IEs when calling initConfig or simply trying to pass components as config to objects sometimes.
Can't see any side effects of fixing this... my application still seems to work...

Would welcome any insights.
Oh, and not checked in 4.2...

Cheers,
Westy

westy
22 Nov 2013, 3:23 AM
My override, for those that may want it:


Ext.define('Altus.overrides.Ext', {
// Null body, intentionally...
},
function() {
/*jsl:ignore*/


// Vars needed by override
var objectPrototype = Object.prototype,
toString = objectPrototype.toString,
enumerables = Ext.enumerables;


Ext.apply(Ext, {
/**
* Override of clone, to stop enumerables being copied when do not actually exist in the object being cloned.
* See: http://www.sencha.com/forum/showthread.php?276579-4.1.3-Ext.clone-adds-enumerables-to-simple-object-in-old-IEs
*/
clone: function(item) {
var type,
i,
j,
k,
clone,
key;


if (item === null || item === undefined) {
return item;
}


// DOM nodes
// TODO proxy this to Ext.Element.clone to handle automatic id attribute changing
// recursively
if (item.nodeType && item.cloneNode) {
return item.cloneNode(true);
}


type = toString.call(item);


// Date
if (type === '[object Date]') {
return new Date(item.getTime());
}




// Array
if (type === '[object Array]') {
i = item.length;


clone = [];


while (i--) {
clone[i] = Ext.clone(item[i]);
}
}
// Object
else if (type === '[object Object]' && item.constructor === Object) {
clone = {};


for (key in item) {
clone[key] = Ext.clone(item[key]);
}


if (enumerables) {
for (j = enumerables.length; j--;) {
k = enumerables[j];
// <WestyFix>
if (item.hasOwnProperty(k)) {
clone[k] = item[k];
}
// </WestyFix>
}
}
}


return clone || item;
}
});
/*jsl:end*/
});

Gary Schlosberg
22 Nov 2013, 6:45 AM
Thanks for the report, and the workaround. I was able to reproduce using your fiddle, but not when I set it to version 4.2.1, so it looks like this was fixed.

westy
22 Nov 2013, 10:05 AM
Ah, just downloaded and looked at the 4.2.2 and my exact change has been made there.That's reassuring.Cheers,Westy