Nested types get messed up when passed to more than one node

I came across some weired behavior: consider the following function node:

class MyArray extends Array{}
class MyThing {
    constructor(){
        this.arr = new MyArray()
    }
}
var thing = new MyThing()
return {payload: thing};

if you connect a debug node to this which prints out msg.payload.arr.constructor.name it will print correctly "MyArray".

But if you connect a second debug node with exactly the same setting, it will print "Array"

here is an MCV flow showing the problem:

[{"id":"3f9bab72.f45d44","type":"function","z":"32bbe58d.19148a","name":"","func":"class MyArray extends Array{}\nclass MyThing {\n constructor(){\n this.arr = new MyArray()\n }\n}\nvar thing = new MyThing()\n\nreturn {payload: thing};","outputs":1,"noerr":0,"x":470,"y":100,"wires":[["d5ae8f14.e3fb3","7abcddf.c434824"]]}]

here is the corresponding bug in my nodes repository https://github.com/enocean-js/enocean-js/issues/111

I wonder if this behaviour is related to the fact that Node-RED clones messages that are send to the additional wires (the first one will get the original msg object).

investigating further, node-red uses clone and apparently the bug is caused by that module. there is already a bug report for this particular problem dating back to 2017... it seems the module is not actively maintained anymore :frowning:

digging even deeper, I found this to work:

class MyArray extends Array{}
class MyThing {
    constructor(){
        this.arr = new MyArray()
    }
}
var thing = new MyThing()

var thing2 = Object.assign(Object.create(thing), thing);

console.log(thing.arr.constructor.name)
console.log(thing2.arr.constructor.name)

though i'm not sure i would want to risk breaking stuff replacing clone with Object.assign(Object.create(thing), thing) ...

How about the using spread syntax for cloning your object ?

Something like:

var thing2 = {...thing};

I don´t remember how it differs from object.assign neither how it handles nested properties. I never needed to go on such advanced level in regards to object creation.

nice one! the spread operator does work... how could I have missed that :wink:
this would work for my message object, but unfortunately, both ways break the unit tests of NR :frowning: