Search code examples
javascriptpropertiesdefineproperty

Why does the behavior of a property defined by Object.defineProperty change if accessed before being used?


Only tested this in Chrome, my application doesn't need to work in any other browser.

For example in the following code (JSFiddle):

function A(a) {
    document.write(this.B);
    this.A = a;
    this.B = a;
}
function A_C(a) {
    this.A = a;
    this.B = a;
}
A.prototype.constructor = A;
A.prototype.C = A_C;
Object.defineProperty(A.prototype, 'B', {
    writeable: true,
    enumerable: true,
    value: '0'
});

var B = A;

var C = new A('A');
var D = new B('B');

document.write(C.A);
document.write(D.A);
document.write(C.B);
document.write(D.B);

C.C('C');
D.C('D');

document.write(C.A);
document.write(D.A);
document.write(C.B);
document.write(D.B);

The output is:

00AB00CD00

Instead of:

00ABABCDCD

Whereas in the following code (JSFiddle):

function A(a) {
    this.A = a;
    this.B = a;
}
function A_C(a) {
    this.A = a;
    this.B = a;
}
A.prototype.constructor = A;
A.prototype.C = A_C;
Object.defineProperty(A.prototype, 'B', {
    writeable: true,
    enumerable: true,
    value: '0'
});

var B = A;

var C = new A('A');
var D = new B('B');

document.write(C.A);
document.write(D.A);
document.write(C.B);
document.write(D.B);

C.C('C');
D.C('D');

document.write(C.A);
document.write(D.A);
document.write(C.B);
document.write(D.B);

The output is:

ABABCDCD

What is going on here?


Solution

  • You mistyped writable:

    writable: true
    

    Works as expected. Fiddle

    writable is false by default, so with a mistyped name it will still be false.


    How you're able to set a non-writable property and it overrides/shadows the prototype one makes no sense, it looks like a bug in the Chrome implementation. This buggy behavior is non-reproducible in Firefox.