# Another question re prototpytes

**URL:** <https://discourse.processing.org/t/another-question-re-prototpytes/21475>\
**Category:** Beginners\
**Created:** [June 1, 2020, 11:02am UTC](https://discourse.processing.org/t/another-question-re-prototpytes/21475 "2020-06-01T11:02:26Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![femke.blanco](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/femke.blanco/32/3431_2.png) [@femke.blanco](https://discourse.processing.org/u/femke.blanco)\
**Post date:** [June 1, 2020, 11:02am UTC](https://discourse.processing.org/t/another-question-re-prototpytes/21475/1 "2020-06-01T11:02:26Z")

</div>

(Please excuse the old technique.)

I am able to add a function to a constructor’s prototype **after** I create an object, and use the function:

```auto
function Thing() {
    this.prop1 = 1;
    this.prop2 = 2;
}
var thing1 = new Thing();
Thing.prototype.change = function () {
    return this.prop1 + this.prop2;
};
alert(thing1.change());//3

```

I am able to reassign a constructor’s prototype **before** I create an object, and use the function:

```auto
function Thing() {}
var thing1 = new Thing();
Thing.prototype.change = function () {
    return this.prop1 + this.prop2;
};
// ...
function DeluxeThing() {
    this.prop1 = 10;
    this.prop2 = 20;
}
DeluxeThing.prototype = Object.create(Thing.prototype);
var deluxeThing1 = new DeluxeThing();
// ...
alert(deluxeThing1.change());//30

```

But I am unable to reassign a constructor’s prototype **after** I create an object, and use the function:

```auto
function Thing() {}
var thing1 = new Thing();
Thing.prototype.change = function () {
    return this.prop1 + this.prop2;
};
// ...
function DeluxeThing() {
    this.prop1 = 10;
    this.prop2 = 20;
}
var deluxeThing1 = new DeluxeThing();
DeluxeThing.prototype = Object.create(Thing.prototype);
// ...
alert(deluxeThing1.change());//TypeError: deluxeThing1.change is not a function

```

Why is the last case so?

Thanks in advance.

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [June 1, 2020, 2:39pm UTC](https://discourse.processing.org/t/another-question-re-prototpytes/21475/2 "2020-06-01T14:39:09Z")

</div>

> [@femke.blanco](#):
>
> But I am unable to reassign a constructor’s prototype **after** I create an object, and use the function:

The following explanation is a continuation of this previous reply:

> [@Javascript: Question re prototpyes](https://discourse.processing.org/t/javascript-question-re-prototpyes/21149/2):
>
> Your posted example above is about classical (I’d say archaic) inheritance. For more than half a decade already the modern way of doing that is via keywords class, extends and super: Below’s your sketch rewritten to use modern inheritance: 'use strict'; class Thingy { change() { return this.char1 + this.char2; } } class Thingamajig extends Thingy { constructor(param1, param2) { super(); this.char1 = param1; this.char2 = param2; } } const thingy1 = new Thin…

In order to understand why the object _deluxeThing1_ can’t find the method Thing::**change()** inherited now by class DeluxeThing, we 1st need to know what actually happens behind-the-scenes when we use the operator `new`:

> **[new - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new)**
>
> The new operator lets developers create an instance of a user-defined object type or of one of the built-in object types that has a constructor function.

Unfortunately the `new`’s reference above isn’t explicitly enough on this part:

> 1. A new object is created, inheriting from `Foo.prototype`.

What it forgets to tell us is that in order for an object to inherit from a _prototype{}_ object, it’s gotta assign that to its ` __proto__ ` “secret” accessor property:

> **[Object.prototype.\_\_proto\_\_ - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto)**
>
> The \_\_proto\_\_ accessor property of Object instances exposes the \[\[Prototype\]\] (either an object or null) of this object.

Therefore right after `var deluxeThing1 = new DeluxeThing();`, _deluxeThing1{}_.` __proto__ ` points to DeluxeThing._prototype{}_.

Afterwards you end up reassigning a new object to DeluxeThing._prototype{}_:  
`DeluxeThing.prototype = Object.create(Thing.prototype);`

However _deluxeThing1{}_.` __proto__ ` still points to the original DeluxeThing._prototype{}_!

That’s why `alert(deluxeThing1.change());` fails, b/c the original DeluxeThing._prototype{}_ doesn’t have any of Thing._prototype{}_'s properties.

As a workaround you could replace Object.[**create()**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create) by Object.**setPrototypeOf()**:  
`Object.setPrototypeOf(DeluxeThing.prototype, Thing.prototype);`

> **[Object.setPrototypeOf() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf)**
>
> The Object.setPrototypeOf() static method sets the prototype (i.e., the internal \[\[Prototype\]\] property) of a specified object to another object or null.

However such approach may interfere w/ that object’s performance forever!

For further knowledge on how JS inheritance chain internals work see this:

> **[Inheritance and the prototype chain - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain)**
>
> In programming, inheritance refers to passing down characteristics from a parent to a child so that a new piece of code can reuse and build upon the features of an existing one. JavaScript implements inheritance by using objects. Each object has an...

But again my advice is that you should stop using ancient JS inheritance techniques and simply embrace the modern ES6 keywords `class`, `extends` and `super`.

You can always transpile your code back to ES5 by pasting it on [BabelJS.io](http://BabelJS.io) for deployment:

> **[Babel · The compiler for next generation JavaScript](https://babeljs.io/repl/#?browsers=defaults,%20not%20ie%2011,%20not%20ie_mob%2011&build=&builtIns=false&spec=false&loose=true&code_lz=OQVwzgpgBGAuBOBLAxrYBuAUJ5AbAhmGFACoAWiAdgOYCeUA3plFMmfjRABQCUjzLKPAiwQ8SlFgUwAOjb54ARigBqSdLnt4AJiwsAvpkM4CRUhRr4AtvgBWialAgAPWBEoATYuSp1-LZAB7Sjh4EFRA-C4ABwVrRQAaKFj4a20-JkEYEGiIKJ49QSlEWXklKABeZLirRUKWYtKtbUrq1KtdAUNjIJDYdV9aZSrKCAB3c0HeBIEs4ssbe2phqFGJnwW7By5EqHSsTHxcPNgueeprLeXNDmpuHgKoAHonqABmIA&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=true&fileSize=true&timeTravel=false&sourceType=module&lineWrap=true&presets=env,es2015-loose,env&prettier=true&targets=&version=7.9.6&externalPlugins=)**
>
> The compiler for next generation JavaScript
