According to ES5, Section 10.5 Declaration Binding Instantiation, Step 5.e.iv, http://es5.github.io/#x10.5 a duplicate global function declaration throws a TypeError exception, when the existing property is not configurable and: - an accessor descriptor, - or, not writable, - or, not enumerable. For example, the following code is supposed to throw a TypeError exception for each duplicate function declaration, "f0", "f1", "f2", and "f3": Object.defineProperty(this, "f0", { "get" : undefined, "set" : undefined, "enumerable" : false, "configurable" : false }); eval(" function f0() { return 0; } "); // TypeError Object.defineProperty(this, "f1", { "value" : 0, "writable" : false, "enumerable" : false, "configurable" : false }); eval(" function f1() { return 0; } "); // TypeError Object.defineProperty(this, "f2", { "value" : 0, "writable" : true, "enumerable" : false, "configurable" : false }); eval(" function f2() { return 0; } "); // TypeError Object.defineProperty(this, "f3", { "value" : 0, "writable" : false, "enumerable" : true, "configurable" : false }); eval(" function f3() { return 0; } "); // TypeError However, Safari does not report any exception, while Chrome and Firefox correctly throw the TypeError exceptions. I've tested this using the Web Inspector console of Safari 7.0.4. Thanks, Daejun
Retitling to reflect actual bug - it's not due to a duplicate function. We're short circuiting creation of a new global property when we decide to shadow and that means we skip the readonly check on the existing property. Whoops.
<rdar://problem/19032865>