Behavior of a Literal Instance

I have an object literal inside, I have another literal. Parent instances set values ​​in order, but not internal. I am confused by this behavior. Why is the behavior of an object literal different?

here http://jsfiddle.net/Lq6frf76/

var vehicle={
    tires : 0,
    seats : { 
        total :0  
    }
}


var Car = Object.create(vehicle);
Car.tires=4;
Car.seats.total = 4 ;

var bike = Object.create(vehicle);
bike.tires=2;
bike.seats.total = 2 ;




console.log(Car.tires);     --->> it is not overwritten not consistent 
console.log(Car.seats.total); -->> it is overwritten here 

console.log(bike.tires);
console.log(bike.seats.total);

      

enter image description here

This is not a duplicate question.

  • I knew alternatives
  • I knew the inner literal would be canceled. I've seen many examples.
  • I don't know why same behavior is not repeated for the parent object

    or in other words

    why is the car.tires value displayed correctly and not overwritten in my example

+3


source to share


1 answer


Edit: Added some more at the end and made a correction

It seems to me that we need to answer here. I apologize if this is bad etiquette (and if this is the wrong answer). Please let me know.

The prototypical inheritance way works in javascript:
When you read a property of an object, say a property of tires

your object Car

, it first checks to see if Car

it has that property. What does it mean if there is a property tires

directly related to the object Car

? Or, in other words, Car

something like this:

{
    tires: 0,
    ...
}

      

And the answer is no. You might think that Object.create()

doing this is similar to what you might do in a constructor, i.e.

function Vehice(t) {
    this.tires = t;
    ...
};
var Car = new Vehicle(4);

      

Everything Object.create()

does makes the object you pass to the prototype

object it returns to you.

So after that, Object.create()

your object looks something like this:

{
    __proto__: //reference to vehicle
}

      

So when it doesn't find tires

one directly attached to an object, it then looks at the prototype, in this case a reference to the object vehicle

you created earlier. The prototype ( vehicle

) has a property tires

, so it returns that value.

Correction

So what happens when you speak Car.tires = 6

? When you write the value of an object property, things work differently. Javascript only looks at whether this object has this writeable property.If the object itself does not have this property, it first checks the prototype chain to make sure the property is not inherited from readonly . If it is not, then it creates this property for the object itself (as long as it is legal to write this property to the object). So now you have something similar to this:

{
    tires: 6,
    __proto__: //reference to vehicle
}

      

End correction

Now when you read a property of an tires

object Car

, it first sees the property tires

in the object itself Car

and returns that value, so it doesn't need to look at the prototype.

This is why you can set a property tires

on one vehicle and not affect the value of others.

Now for the property seats.total

. When you read the property seats

, everything works the same. The object has Car

no property seats

, so it looks at the prototype that has it. Then it checks the referenced object seats

to see if it has a property total

that it directly binds to it, and it does so, so it just returns that value.



Now when you want to write a property total

, things will be different again. The assertion is as follows: Car.seats.total = 4

. What happens here is that you are setting the property total

to the object that the property is referring toseats

.

Javascript must first find the object that is being referenced seats

. It does this by checking if it is a property of the object itself Car

. It doesn't, so it checks the prototype where it finds the property seats

. It can now write a property total

to an object seats

as we saw earlier, but note that this happens to the seats

prototype property , which is the reference for the vehicle

previously defined and shared object bike

.

In other words, javascript doesn't see that you are writing a property of an object Car

, so it doesn't create a property of an seats

object Car

and assigns a new object to it, and then a property total

on that object and assign it 4

.

Now, when you're trying to read a property bike

seats

, javascript will first look whether the property is bike

a property seats

, directly attached to it. It doesn't, so it looks like a prototype bike

that has it and returns a modified object vehicle.seats

.

Hopefully this clarifies what's going on and answers your questions. Let me know if any part is not clear and I hope someone will correct me if I'm just wrong!

Addendum: I think from the traditional OO language, how it works for tires

, you would expect this to happen: you inherit the initial value, but if you change it, you can't expect it to change for every other instance vehicle

.

The javascript way makes it very space efficient. Only initially the prototype has a property, if you have a thousand objects inheriting from vehicle

and only 2 of them set the property tires

, you only used space for three Number

instead of a thousand.

As far as the way of working with seats

, I suppose they could design a language to determine if you set an inheritable object

( seats

) property and then copy the entire object into an instance.I suppose this would actually make the system less flexible and more complex. If you want to Car

have your own version seats

, you could specify it like this:

var car2 = Object.create(vehicle, {
    seats: {
        value: {
            count: vehicle.seats.total
        }
    }
});

      

or like this:

var car2 = Object.create(vehicle);
car2.seats = { count: vehicle.seats.total }; //create a new object like the one attached to vehicle

      

Does the last example mean what's going on?

To me in this case, an explicit constructor version of this would be more natural, but with javascript we can use constructors or `Object.create () or various combinations of them to do what we want.

Ultimately though, each set comes in two parts. First, find the object we are setting the property on; Finally, set the property. Everything before this ending .

, just to take the first step:

Car.seats.count = 10

means that the property of the count

object being referenced Car.seats

is 10. Which object Car.seats

? We now follow the rules for reading a property, not writing. Car

has no property seats

, so see if it inherits from it. If it is not, it Car.seats

will return undefined

, and trying to set the property to non undefined

will throw an error. If it inherits from it, it Car.seats

will return an object from somewhere down the prototype chain, in this case the object being referenced vehicle

. This object has a property count

, so just set it to 10.

Car.tires = 4

means the property of the tires

object being referenced does not have a Car

4. Car

property tires

, so make sure we are allowed to create it and then do so.

Hope this clears things up. Sorry for writing so much, but it really helped solidify these concepts for me. Plus I learned some ECMAScript 5 stuff that I blissfully ignored :-)

+1


source







All Articles