Safari 4 Beta Breaks Class.implement()
I just spent a few hours tracking down this lovely bug that broke my portfolio page in Safari 4 Beta (build 5528.16). If you add a property to a constructor’s prototype after initializing an object from that constructor, then that new property will not be enumerable in a for-in loop (presumably it’s been mistakenly marked DontEnum).
(update: The May 12th update to Safari 4 – build 5528.17 – fixes this issue, woohoo)
I first discovered this when the oneEvent method that I added to the Events Class was not getting implemented into my other Classes. The JS.Class blog mentioned a Function.prototype enumeration bug that may be related, but other than that I couldn’t find any mention of this problem on Google.
Here is the reduction that I submitted to Apple:
// constructor
var House = function() {};
House.prototype = {
garage : 1,
yard : 1
};
// this works
var house = new House;
for (var prop in house)
print('house has a ' + prop);
// add a new property after using constructor
House.prototype.pool = 1;
// we can see the pool in the prototype
for (var prop in House.prototype)
print('blueprint contains ' + prop);
// enumeration won't find the pool
var mansion = new House;
for (var prop in mansion)
print('mansion has a ' + prop);
// but the pool is there
print('check for pool in house...' + !!house.pool);
print('check for pool in mansion...' + !!mansion.pool);
function print(line) { document.write(line + '<br/>'); }
Which in Safari 4 Beta, yields…
house has a garage
house has a yard
pool now added to blueprint
blueprint contains garage
blueprint contains yard
blueprint contains pool
mansion has a garage
mansion has a yard
check for pool in house...true
check for pool in mansion...true
The line, mansion has a pool, is never printed in Safari 4 Beta! It does, however, get printed in the latest Webkit Nightly, but I’m not sure when this bug was fixed and if Apple has merged that fix into their Safari 4 branch. I hope they have already, and if not, that they do so when they read my bug report.
I hope this helped put somebody’s mind at ease.