Question regarding ES5

# Irakli Gozalishvili (15 years ago)

I've run into one issue and even after reading ES5 specs several times it's not clear to me what should be an expected behavior:

Currently on Firefox nightly following code:

(function() { "use strict";

function Type() {} Object.freeze(Type.prototype); var object = Object.create(Type.prototype); object.constructor = function Foo() {};

return object })();

throws TypeError: object.constructor is read-only while on chrome

it returns object with constructor Foo

I would like to know what is an expected behavior to fill a bug to an appropriate project.

Thanks!

Irakli Gozalishvili Web: www.jeditoolkit.com Address: 29 Rue Saint-Georges, 75009 Paris, France goo.gl/maps/3CHu

# Allen Wirfs-Brock (15 years ago)

The error looks correct to me. By freezing Type.proto you make all its own properties "read only". One of those is the constructor that is automatically created on every func.prototype object. When you assign to object.constructor you are trying to over-ride an inherited read-onoy property. ECMAScript has never allowed this. You can say: Object.defineProperty(object,"constructor",{value: function Foo() {}, /* any other attributes you want to set */}); to over-ride the inherited constructor property. Or you can restructure you code so you do the freeze after you do the assignment.

# Irakli Gozalishvili (15 years ago)

Thanks for the reply Allen,

I was under the impression that inherited properties can be overridden, regardless of their write-ability on the proto.

Also as far as I understand freeze will make properties including constructor non-confugurable, will I still be able to override such properties using Object.defineProperty ?

Also this was simplified example and it's not really possible to do the freeze after. Will try Object.defineProprety though.

Thanks

Irakli Gozalishvili Web: www.jeditoolkit.com Address: 29 Rue Saint-Georges, 75009 Paris, France goo.gl/maps/3CHu

# Irakli Gozalishvili (15 years ago)

I have not found a way to cc people but here is the link for a bug report:

code.google.com/p/v8/issues/detail?id=1169

I think if you'll star it you'll get an updates over email.

-- Irakli Gozalishvili Web: www.jeditoolkit.com Address: 29 Rue Saint-Georges, 75009 Paris, France goo.gl/maps/3CHu

# Allen Wirfs-Brock (15 years ago)

They can be over-ridden by Object.defineOwnProperty. they cannot be over-ridden by assignment. See ES5 [[CanPut]] specification 8.12.4. step 8.b

# Jeff Walden (15 years ago)

On 02/16/2011 05:32 PM, Irakli Gozalishvili wrote:

I was under the impression that inherited properties can be overridden, regardless of their write-ability on the proto.

Here's another take on this -- same idea, just another statement of it.

You can override any inherited property. You just have to be explicit that you are overriding. As you'd do if the inherited property were an accessor get/set pair, so you do if the inherited property is not writable. If you want to override, don't set the property by =, define it with Object.defineProperty.

# Oliver Hunt (15 years ago)

This behaviour seems to result in undesirable behaviour in conjunction with object literals:

Object.defineProperty(Object.prototype, "foo", {value:"bar"});

"use strict"; var someObject = {foo:"wibble"}

Will now throw.

# Mark S. Miller (15 years ago)

On Wed, Feb 16, 2011 at 8:07 PM, Oliver Hunt <oliver at apple.com> wrote:

This behaviour seems to result in undesirable behaviour in conjunction with object literals:

Object.defineProperty(Object.prototype, "foo", {value:"bar"});

"use strict"; var someObject = {foo:"wibble"}

Will now throw.

It should not throw, since ES5 object and array literals are defined in terms of [[DefineOwnProperty]] rather than [[Put]]. This is a change from ES3.

Just tested, and FF4 beta has the right behavior in both cases: throwing on assignment and not on object literals. Neither Chrome nor Safari throw in either case.

# Dmitry A. Soshnikov (15 years ago)

Very strange behavior. What's the rationale? To avoid a shadowing? To avoid typo-errors -- i.e. if a user uses assignment it may be occasionally and if he uses Object.defineProperty -- he really wants to do it? Looks inconsistently. Assignment always affected an own property (only if the property isn't an accessor, then of course it affects the parent object).

Dmitry.

# Brendan Eich (15 years ago)

On Feb 17, 2011, at 12:17 AM, Dmitry A. Soshnikov wrote:

Very strange behavior. What's the rationale? To avoid a shadowing? To avoid typo-errors -- i.e. if a user uses assignment it may be occasionally and if he uses Object.defineProperty -- he really wants to do it? Looks inconsistently. Assignment always affected an own property (only if the property isn't an accessor, then of course it affects the parent object).

No, assignment that would shadow a readonly prototype-property in ES1-3 was a silent failure. See 8.6.2.3 [[CanPut]] and 8.6.2.2 [[Put]].

# Dmitry A. Soshnikov (15 years ago)

On 17.02.2011 11:22, Brendan Eich wrote:

On Feb 17, 2011, at 12:17 AM, Dmitry A. Soshnikov wrote:

Very strange behavior. What's the rationale? To avoid a shadowing? To avoid typo-errors -- i.e. if a user uses assignment it may be occasionally and if he uses Object.defineProperty -- he really wants to do it? Looks inconsistently. Assignment always affected an own property (only if the property isn't an accessor, then of course it affects the parent object). No, assignment that would shadow a readonly prototype-property in ES1-3 was a silent failure. See 8.6.2.3 [[CanPut]] and 8.6.2.2 [[Put]].

Hm, really. Never thought -- probably because there were no use cases in ES3 for me. Checked in ES3:

var o = {proto: Object}; o.prototype = 10; console.log(o.prototype); // still Object.prototype

Thanks, it was new for me.

Dmitry.