3

Following is my Class, Its prototype vale is not getting changed, (I am working on the Chrome console)

class Rectangle {
    constructor(length, width) {
        this.length = length;
        this.width = width;
    }

    getArea() {
        return this.length * this.width;
    }

    static create(length, width) {
        return new Rectangle(length, width);
    }
}

and I am Changing the prototype of the Class to null

Rectangle.prototype= null

When I try to access the changed Prototype, the value remains the same "Object" with 'getArea' prototype property of Rectangle

But in ES5 the prototype value is changed.

Ignatius Andrew
  • 8,012
  • 3
  • 54
  • 54
  • Edited the Question, did not mean the plain object as a result of null assingment – Ignatius Andrew Jun 07 '16 at 13:46
  • I misread your question, sorry. Deleted the comment. – nils Jun 07 '16 at 14:07
  • A class's prototype is non-writable, if you really want to overwrite the prototype, use `function` instead, a function's prototype is writable, you can reassign it to any object you want. – lochiwei May 20 '22 at 15:04

2 Answers2

4

In ES6, the .prototype property of classes is not writable and not configurable1. Use strict mode where you do the assignment and you'll get ReferenceError exception "Invalid assignment in strict mode".

If you want to overwrite the .prototype (which is a very bad idea in general), you'll have to use Object.defineProperty(Rectangle, "prototype", {value: …}).

1: See §14.5.14 ClassDefinitionEvaluation, step 16: Perform MakeConstructor(F, writablePrototype=false, prototype=proto).

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Hello! The `prototype` property of an ES6 class in non-configurable, so this answer won't work. Is there any other way? I'd like to wrap the class `prototype` with a Proxy. – trusktr Nov 17 '19 at 21:57
  • 1
    @trusktr Thanks for the hint. I guess for that you would have to use an ES5 class definition, which you can still use in a `class extends` clause. Alternatively change your ES6 constructor to return an instance wrapped in a proxy (you can re-use the handler object). See also [this answer](https://stackoverflow.com/a/31236132/1048572) for a similar undertaking. – Bergi Nov 17 '19 at 22:09
0

In ES6 prototype property is handled in a special way as non-configurable. But one can use the Object.setPrototypeOf of Object to set a new value to the prototype of an object X, eg:

Object.setPrototypeOf(X, proto)

class Rectangle {
    constructor(length, width) {
        this.length = length;
        this.width = width;
    }

    getArea() {
        return this.length * this.width;
    }

    static create(length, width) {
        return new Rectangle(length, width);
    }
}

Rectangle.prototype = null;
console.log(Object.getPrototypeOf(Rectangle));

Object.setPrototypeOf(Rectangle, null);
console.log(Object.getPrototypeOf(Rectangle));

You are warned that altering the prototype of objects has various side-effects, including performance issues and possible inheritance issues.

Unfortunately the following won't work because prototype is set as non-configurable initially.

Object.defineProperty(X, "prototype", {value: proto});
Nikos M.
  • 8,033
  • 4
  • 36
  • 43