# Confusion about object prototype

**URL:** <https://discourse.nodered.org/t/confusion-about-object-prototype/32605>\
**Category:** Developing Nodes\
**Created:** [8 September 2020 20:59 UTC](https://discourse.nodered.org/t/confusion-about-object-prototype/32605 "2020-09-08T20:59:03Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [8 September 2020 20:59 UTC](https://discourse.nodered.org/t/confusion-about-object-prototype/32605/1 "2020-09-08T20:59:03Z")

</div>

Hi folks,

I'm working together with our friend @Paul-Reed on a new node.  
But now we are completely stuck...

We create an object and pass it to a third-party library:

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/7/e/7e4fc8397356a50540176690fb341310db06bd1b.png)

The library checks whether it is a plain object:

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/d/5/d57baeac1a459af7be80e66dfc8a18bbdf86086d.png)

However seems that the second check fails:

```auto
Object.getPrototypeOf(obj) === Object.prototype

```

So I installed an npm library to find the differences between both prototypes, but it gives me no differences:

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/5/5/557985b404ed36402fa587e27d78d922e33d7367.png)

And when I convert the object to a json string and back to an object it is also fine:

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/8/6/8677297fb7d8a6b797a1b16d78a2467447fb2a6e.png)

I have no clue what is going wrong 🥴

Does anybody can explain this behaviour and how I can solve it (without converting to a string and back)?

Thanks !!!!  
Bart

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [8 September 2020 21:08 UTC](https://discourse.nodered.org/t/confusion-about-object-prototype/32605/2 "2020-09-08T21:08:23Z")

</div>

Not an answer, but why are you doing the 2nd check? The first is surely good enough.

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [8 September 2020 21:09 UTC](https://discourse.nodered.org/t/confusion-about-object-prototype/32605/3 "2020-09-08T21:09:05Z")

</div>

Hey Julian, that is not our check. It is code inside the Plotly library ...

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [8 September 2020 21:16 UTC](https://discourse.nodered.org/t/confusion-about-object-prototype/32605/4 "2020-09-08T21:16:41Z")

</div>

OK, can you stick in a `console.log` of the `obj`? My guess is that it is receiving something that is an object not built from the Object.prototype.

---

<div class="post-metadata">

**Author:** ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)\
**Post date:** [8 September 2020 21:19 UTC](https://discourse.nodered.org/t/confusion-about-object-prototype/32605/5 "2020-09-08T21:19:11Z")

</div>

Is the Function node involved at all?

This type of error can be caused by a gotcha with the Sandbox used inside the Function node.

The Sandbox gets its very own instance of Object. That means the prototype of an object created inside the Function node will _not_ be the exact same thing as the prototype of the Object outside of the Sandbox.

The prototypes will be identical - but they will be separate instances of it - so the strict equality check will fail.

---

<div class="post-metadata">

**Author:** ![cinhcet](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cinhcet/32/438_2.png) [@cinhcet](https://discourse.nodered.org/u/cinhcet)\
**Post date:** [8 September 2020 21:22 UTC](https://discourse.nodered.org/t/confusion-about-object-prototype/32605/6 "2020-09-08T21:22:27Z")

</div>

how exactly do you create `plotlyConfig.layout` ?

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [8 September 2020 21:35 UTC](https://discourse.nodered.org/t/confusion-about-object-prototype/32605/7 "2020-09-08T21:35:28Z")

</div>

> [@cinhcet](#):
>
> how exactly do you create `plotlyConfig.layout` ?

Not really rocket science:

```auto
var plotlyConfig = {};
plotlyConfig.layout = {};
// Then the layout property is filled with sub-properties ...

```

> [@knolleary](#):
>
> The Sandbox gets its very own instance of Object. That means the prototype of an object created inside the Function node will _not_ be the exact same thing as the prototype of the Object outside of the Sandbox.

Damn, don't know how you do it...  
You are getting very warm ...  
Plotly is made to run in the browser. But if you want to run it on the server - like we do for some features like validations - I needed to load it into [JsDom](https://github.com/jsdom/jsdom). And JsDom uses the [vm](https://github.com/jsdom/jsdom) package, just like the function node:

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/0/9/09677053a36b2bfb4cc935243f027397ab1301bb.png)

Then it probably won't be easy to workaround this ...

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [8 September 2020 21:58 UTC](https://discourse.nodered.org/t/confusion-about-object-prototype/32605/8 "2020-09-08T21:58:32Z")

</div>

It [seems](https://github.com/jsdom/jsdom#interfacing-with-the-nodejs-vm-module-using-getinternalvmcontext) that I can get access to Plotly's internal vm context.  
Perhaps I can use that (somehow) to _create my instance inside the vm_, to make sure it gets the correct prototype.  
Something like this:

```auto
const createInstanceScript = new Script(`
   var plotlyConfig = {};
   plotlyConfig.layout = {};
   // Then the layout property is filled with sub-properties ...
`);

const jsDomVmContext = dom.getInternalVMContext();

createInstanceScript.runInContext(jsDomVmContext );

```

Although then I don't have access to my variable from my node ...  
My time is up for today. If somebody has any ideas meanwhile, please let me know.

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [9 September 2020 21:49 UTC](https://discourse.nodered.org/t/confusion-about-object-prototype/32605/9 "2020-09-09T21:49:21Z")

</div>

I managed to workaround it.  
Here is the code, but I assume there is no poor soul on this planet that will ever need it ...  
Anyway:

```auto
// Script to create a global variable
const script = new vm.Script(`
   this.plotlyConfig = {};
`);

// Execute the script in the VM, so that the global variable will be created in the VM context
const vmContext = jsDomInstance.getInternalVMContext();
script.runInContext(vmContext);

// Get the global variable from the VM context
var plotlyConfig = jsDomInstance.window.plotlyConfig;

// Manipulate the content of the global variable in the Node-RED node
plotlyConfig.someProperty = "someValue";

// Now you can call a function of the VM, and pass the plotlyConfig variable as a parameter ...

```

Since the variable has been created inside the VM context, its prototype will get through the check inside the VM ...

Without Nicks comment, I would most probably never have found the root cause in my current life ...

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [9 September 2020 22:22 UTC](https://discourse.nodered.org/t/confusion-about-object-prototype/32605/10 "2020-09-09T22:22:52Z")

</div>

The code snippet in my last post worked fine for a few objects. But I needed to add a large number of objects and arrays. And all those also needed to have a prototype from the VM, and I don't know in advance how much properties the user will add 🥶

So instead of creating a fixed number of instances in the VM, I got an idea to add two functions to the VM context. One function to create an _ **object** _ in the VM, and one to create an _ **array** _ in the VM:

```auto
// Script to add global functions (to create a Javascript object or array) in the server DOM context
const script = new vm.Script(`
   function createObject() {
      return {};
   }
            
   function createArray() {
      return [];
    }
`);

// Execute the script in the VM (of jsDom), so that the global function is added to the VM context
const vmContext = ´jsDomInstance.getInternalVMContext();
script.runInContext(vmContext);

```

Now in my node I can do this all over the place:

- Replace `someVar = {}` by `someVar = jsDomInstance.window.createObject()`
- Replace `someVar = []` by `someVar = jsDomInstance.window.createArray()`

That is more like it ...

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [23 September 2020 22:22 UTC](https://discourse.nodered.org/t/confusion-about-object-prototype/32605/11 "2020-09-23T22:22:52Z")

</div>

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.
