简体   繁体   中英

Object inheritance / import issue

Im trying to wrap my head round this problem. Not sure its connected to Vue or imports or whatever.

Im importing two different objects (A & B) that import a mutual third object (C). If I assign object A (that contains object C) to a variable New and add some properties to New, object B (that also contains object C) inherits those changes.

I cant figure out why since I havent changed object C..

Ive tried to make the smallest possible example: https://codesandbox.io/s/vue-template-txdfb

This is not related to either Vue or imports, but to JavaScript, and more broadly, storing variables. In JavaScript (and other programming languages), variables are often either stored by value or by reference .

When stored by value, the address points to the actual value in memory, and this is how primitive values (Numbers, Strings, etc) are stored in JavaScript:

let x = 5; // Primitive, by value

By contrast, objects and arrays are stored by reference. That means that when you set another variable equal to your object reference, it will point to the reference, not the value itself:

let x = {
  name: 'My Object'
}
let y = x;
console.log(x === y) // true

The true result of the strict equality operator means they are the exact same object, not an original and a clone. Changing x anywhere will also change y , since they point to the same object.

Similarly, any code that imports an object will be importing a reference to it, and so will see any changes made to the object from elsewhere.

In the codesandbox the object C is referred to as extra .

You then have this line:

this.componentConfig.extra.id.push(this.id);

The property this.componentConfig.extra is referring to the object extra . So C has been changed.

While the extra levels of wrapping and importing make it more difficult to see, what you've got is essentially just this:

 const c = { name: 'John' } const a = { c } const b = { c } acname = 'Emma' console.log(bcname)

In the code above ac and bc are both pointing at the same object. There is no inheriting or copying going on.

Perhaps a diagram will help:

a                                       b
{                                       }
  c -------> { name: 'John' } <------- c
}                                       {

By way of an analogy, John Smith may be referred to as either John or Mr Smith. These two names refer to the same person. If John loses his hat then so does Mr Smith. You can't make a change to John without also changing Mr Smith because they are one and the same.

This is because you are pointed to a reference of an object You can make a shallow clone of the object and then change it and leave the original object as is

eg

const newObject = { ...originalObject }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM