Stop Low Resolution Warning Sign

Transcript

Transcript of the tutorial. TOP


          
        
          So then we've seen most of the types in JavaScript.

          Now all these different things down here, we've still not touched on symbols yet, but we will cover
          
          that in a later chapter.
          
          So now we know a bit more about objects.
          
          I'd like to introduce the idea of primitive and reference types.
          
          Now, I don't want to get too bogged down with this right now and we will be revisiting it later.
          
          But I do want you to understand the basic concepts.
          
          So then what are primitive types and what are reference types?
          
          Well, in JavaScript, primitive types are numbers, strings, booleans, null, undefined and symbols.
          
          So that's six out of the seven types in JavaScript that are primitive types.
          
          Now reference types are the object type, so any kind of object object literals arrays, functions,
          
          dates and all other objects like the math object, these all fall under the object category, the object
          
          type, and they are all reference types.
          
          So we have primitive types and reference types.
          
          But what does this mean exactly?
          
          What is the difference between primitive types and reference types?
          
          Well, it's all to do with how they are stored and used in memory.
          
          So when we create a primitive value, like a new string or a new number or a boolean, and we assign
          
          it to a variable, that value is stored on something called the stack like this.
          
          Now the stack is just a stack of different values in memory and they can be accessed pretty quickly
          
          when we need to use one.
          
          But the space inside the stack is quite limited.
          
          So when we create a reference type like an object literal or an array that is stored not on the stack,
          
          but on what is known as the heap.
          
          Now the heap has more space available so it can hold bigger and more complex types like objects and
          
          arrays.
          
          But it's a bit slower too.
          
          So primitive types are stored on the stack, which is a bit quicker and reference types are stored on
          
          the heap.
          
          That's two different parts of memory for two different things.
          
          But why is this so important?
          
          Well, when we store a primitive value in a variable, it adds that value to the stack and it locks
          
          the variable name to it as an accessor to that value.
          
          So it knows whenever we want to access the variable score, for example, to go out and grab this value
          
          for us.
          
          So when we store a reference type in a variable like an object, it adds the object to the heap and
          
          then it adds a pointer to that object on the stack.
          
          So say for example, we make an array, it adds that array to the heap and we store this array in a
          
          variable.
          
          It adds a pointer to that array in the stack, and then it locks this variable name names to the pointer.
          
          So when we access this variable in the future, it knows to get this pointer which points to this thing
          
          on the heap and it grabs that array for us.
          
          Now you might still be thinking that this is not important at all, but it is and it does have ramifications
          
          and it will affect the way that we code.
          
          So let's just go back to virtually an empty stack and an empty heap.
          
          Now imagine we create this variable score one and we set it equal to a number 50.
          
          Now this is a primitive type, so it's stored down here on the stack and the variable name is locked
          
          to that value.
          
          So when we try to access it in the future, it knows to grab this value.
          
          Now, what if we make a copy of this variable?
          
          If we create a new constant called Score two and we set it equal to score one?
          
          Well, what that does, because this is a primitive type and primitive types are stored on the stack.
          
          It creates a copy of the number and it stores that number separately on the stack.
          
          And this variable name score two is now locked to this new number.
          
          So we have two values now, two different values.
          
          Well, they're the same, but they're two different positions in memory on the stack.
          
          And we have two different variables locked into those.
          
          So in the future, if we were to say score one is now equal to 100, it just updates this value down
          
          here, which is attached to the score one variable.
          
          It doesn't affect this.
          
          This is still 50 and that's completely normal behavior, probably something you would expect to happen.
          
          Now, what if we do this with different types of data reference types?
          
          Well, imagine we create a new constant user one and set it equal to an object.
          
          Well, that object is then stored on the heap because this is a reference type.
          
          Now we have a pointer to that object on the stack and the variable name user one is locked in to that
          
          pointer.
          
          So in the future, if we try to access user one, it's going to find this pointer which points to the
          
          object and return this object back to us.
          
          Now if we create a copy of user one, if we say a new variable, user two is equal to user one, what's
          
          going to happen?
          
          Well, it doesn't create a new object on the heap this time.
          
          What it does is it copies the pointer, doesn't copy the object on the heap, it copies the pointer
          
          and we have our new variable user two locked to this.
          
          New pointer.
          
          So they both point now to the same object on the heap.
          
          So if in the future I now say, okay, well user one is now going to get updated, I'm going to change
          
          the score to 50.
          
          So now this new object is stored on the heap.
          
          And what that means is if we access user one in the future, it's going to get this pointer which points
          
          to the object and bring back this object.
          
          If we access user two, it gets this pointer.
          
          This also points to the same object and that gets that object as well.
          
          So when we update user one, it's also really updating user two because they both point to the same
          
          object.
          
          So this might not be the behavior that you'd expect when you first come to JavaScript.
          
          When we make copies of primitive values like strings and numbers and booleans, we make a new copy of
          
          the value on the stack.
          
          When we try to make a copy of a reference type, we only make a copy of the pointer on the stack, which
          
          points to the same data on the heap.
          
          We don't make a copy of the actual data, so when we then change the copies, it does have an effect
          
          on the original value and vice versa.
          
          So let's see what this means in the code.
          
          So let's take what we've just learned about primitive and reference types and see in action.
          
          So, you know, when we come across this kind of behavior in the future, what's going on?
          
          So primitive values.
          
          First of all, I have right here a variable score one, and we've set it equal to 50.
          
          Then I'm making a copy of that variable.
          
          I'm saying let this new variable score to equal to score one.
          
          Now remember, that creates a copy of that value and stores it separately on the stack because this
          
          is a primitive value.
          
          Now down here, I'm just logging to the console, a template string where we're outputting score one
          
          and also score two.
          
          So let's have a look at this.
          
          They should both be 50, right?
          
          Score one is 50 and score two is 50.
          
          Okay, now imagine we changed score one.
          
          So let's do that.
          
          Let's say now score one is equal to 100.
          
          And now I'm going to just grab this and paste it down here again so we have it output before the change
          
          and after the change.
          
          So if we save it, we can see that score one after the change is now 100 and score two is still 50.
          
          So when we make a copy of primitive values like this, if we change one of them, it doesn't affect
          
          the other.
          
          Now let's comment this out and come down to a reference value.
          
          So a reference types.
          
          So down here I've created a variable or rather try to I'll use a const keyword there and a const keyword
          
          here as well.
          
          And what I'm doing now is creating a new object and that has a name and an age property.
          
          Then I'm creating a copy of that variable of that object.
          
          User two We're setting it equal to what user one is.
          
          So remember, this is a reference type, it's an object.
          
          So this object is stored on the heap and we get a pointer locked to this variable stored on the stack.
          
          Now when we create a copy, it doesn't copy the actual object, it just copies the pointer on the stack.
          
          And then user two is locked to that new pointer.
          
          But they both still point to this same object.
          
          Now when we log both of these users out down here, we should see the same object and we do Ryu and
          
          Ryu 30 and 30.
          
          Now then, if I try to change the name of one of these and I'll just do that by saying user one dot
          
          age is now equal to 40 or something like that.
          
          Then if I copy this again and paste it down here, we can see that now it changes both of them.
          
          They're both now 40 because remember it's only stored once on the heap.
          
          So if we change that value, it's changing it on the heap.
          
          And then both of these pointers, User one and user two are pointing to that same object.
          
          So if we update one, it updates the other and it doesn't matter if I update 1 or 2 here because they're
          
          both pointing to the same thing.
          
          If I change this to two, we're still going to get exactly the same result and we could do something
          
          instead like the name.
          
          We'll change the name to Chun-li.
          
          So let's do that right here.
          
          Save it.
          
          And now we can see they both are Chun-li.
          
          Okay, so that is primitive and reference types.
          
          This is the kind of behavior you need to watch out for in the future when you're coding, because you
          
          might do this at some point thinking that now we have two completely separate values when we make a
          
          copy, but in fact we don't because they're reference types and they're stored once with two separate
          
          pointers.
          
          So that's the basics of primitive and reference types.
          
          Whenever this will be affecting our code in the future, I will be sure to warn you.