Coding

JavaScript – Reference vs Primitive Values/ Types

  • 00:00:02 welcome to this video a father would be
  • 00:00:05 time to have a look at something which
  • 00:00:07 is not related to you one of the ongoing
  • 00:00:09 series right now but something which I
  • 00:00:12 see being asked rather often in the
  • 00:00:14 comments and questions are you to me
  • 00:00:16 everywhere a common source of errors the
  • 00:00:20 difference between primitive and
  • 00:00:22 reference types in JavaScript now what
  • 00:00:26 is both and how does it work
  • 00:00:27 that is what we'll take a look at in
  • 00:00:29 this video and that might explain why
  • 00:00:32 the last time you copied a JavaScript
  • 00:00:35 object and then changed it somewhere
  • 00:00:37 else your copied object was messed up
  • 00:00:40 too so let's have a look at what these
  • 00:00:43 are and how they work as I just said we
  • 00:00:46 have primitive values and we got
  • 00:00:48 reference values or types of JavaScript
  • 00:00:51 you might be aware that javascript is a
  • 00:00:54 dynamically typed language and we don't
  • 00:00:56 have strong typing's which means we
  • 00:00:59 don't define types at the point of time
  • 00:01:01 we declare a variable we just have our
  • 00:01:03 name equals and then some value a string
  • 00:01:06 for example but we do have these types
  • 00:01:09 we do have strings where you have
  • 00:01:10 numbers we just don't explicitly declare
  • 00:01:13 which type of values a variable may hold
  • 00:01:15 but we do have types and primitive
  • 00:01:18 values or types are strings boolean's
  • 00:01:21 numbers undefined now and if we also
  • 00:01:25 count es6 in although the symbol now
  • 00:01:29 these are primitive types and what does
  • 00:01:33 that mean how do you primitive types
  • 00:01:36 work let's take a closer look before we
  • 00:01:38 have a look at reference values to take
  • 00:01:41 a closer look i'm simply on jsbin comm
  • 00:01:44 and I make sure that I only have two
  • 00:01:45 JavaScript and the developer console
  • 00:01:47 open now let's have a look at such a
  • 00:01:50 very simple type I'm going to create a
  • 00:01:52 new variable with the Guara keywords I'm
  • 00:01:55 using ES five-year and I'll name it name
  • 00:01:58 and I want to store my name in there max
  • 00:02:01 now of course their file log name to the
  • 00:02:04 console and we can log it either by
  • 00:02:07 hitting run year or simply hitting ctrl
  • 00:02:09 + Enter we see max and that shouldn't be
  • 00:02:12 too surprising now if I cry
  • 00:02:15 a new variable second name and I assign
  • 00:02:18 name as a value what do you expect to
  • 00:02:22 see if I now print second name well
  • 00:02:25 let's find out by hitting ctrl enter or
  • 00:02:27 first let's clear it now it's run what
  • 00:02:30 we see max twice now for both console
  • 00:02:33 logs we see max and that makes sense we
  • 00:02:36 assigned name as a value for second name
  • 00:02:39 and since name was max second name also
  • 00:02:42 is max those kind of what we would have
  • 00:02:45 expected right now it becomes
  • 00:02:48 interesting if we change name here Q
  • 00:02:51 let's say Chris now if we log second
  • 00:02:58 name again what do you expect to see
  • 00:03:00 keep in mind
  • 00:03:01 second name is assigned name as a value
  • 00:03:05 so name is assigned as a value for
  • 00:03:07 second name I should say now we changed
  • 00:03:09 name and now I do log second name to the
  • 00:03:12 console what do you expect to see here
  • 00:03:14 well that's clear and then hit run we
  • 00:03:18 see max three times so even though I
  • 00:03:20 changed name to Chris since I log second
  • 00:03:24 name here second name still is max
  • 00:03:27 because that's the super important thing
  • 00:03:30 a string and name just is of type string
  • 00:03:33 since the assignor string is a primitive
  • 00:03:36 value and primitive values are copied by
  • 00:03:40 value you could say so if I assign name
  • 00:03:44 as a value for second name it actually
  • 00:03:47 just takes the content of name the value
  • 00:03:50 max and copies it and kind of paste it
  • 00:03:54 as a value for second name so now we
  • 00:03:57 have cue names which are at this point
  • 00:03:59 of time are equal in our memory and when
  • 00:04:02 I reassign name – Chris well then only
  • 00:04:05 one of these two things in memory is
  • 00:04:08 chris the other one second name still is
  • 00:04:11 max that was a lot of talking about
  • 00:04:13 something which probably was obvious to
  • 00:04:16 you but it is important to understand
  • 00:04:19 this to understand what reference types
  • 00:04:22 are and how they work I will show you
  • 00:04:25 how reference type work before we go on
  • 00:04:28 to the slide
  • 00:04:29 let's create a new variable here I will
  • 00:04:33 name it person and it will be a
  • 00:04:34 JavaScript object now this object may
  • 00:04:37 have a age let's say 28 and it may also
  • 00:04:40 have a name property which is not
  • 00:04:42 related to this name variable here at
  • 00:04:44 all that name property could also be max
  • 00:04:46 and of course we could also have more
  • 00:04:49 properties here like hobbies which could
  • 00:04:51 be an array and this array could hold
  • 00:04:53 sports and cooking maybe now if I lock
  • 00:04:58 that person here let's see what happens
  • 00:05:01 if I clear and hit run well we see the
  • 00:05:05 object with hobbiest name and so on so
  • 00:05:08 we simply log what we created here not
  • 00:05:10 that amazing let's create a new variable
  • 00:05:14 second person and let's assign person as
  • 00:05:17 a value let's now log second person so
  • 00:05:21 this new variable to the console if I
  • 00:05:23 clear this and hit run we see this being
  • 00:05:27 logged queue so this statement here
  • 00:05:30 stems from this console.log statement
  • 00:05:32 and it clearly is the same person we
  • 00:05:33 created here no wonder because we copied
  • 00:05:36 it right we assign the value of person
  • 00:05:39 as a value to second person and
  • 00:05:41 therefore as we already learned up there
  • 00:05:44 with Chris and Max we copied the value
  • 00:05:46 so here's the thing we should expect if
  • 00:05:49 I change the name of the person solve
  • 00:05:52 this original object here to Chris now
  • 00:05:55 and now I again log second person
  • 00:06:00 following the logic we saw up here for
  • 00:06:03 the name which was a string we would now
  • 00:06:06 expect to still see our original object
  • 00:06:09 where the name is max now since I'm
  • 00:06:12 talking like this you can probably
  • 00:06:13 imagine that if I hit run now well we
  • 00:06:16 see a new object with Chris instead of
  • 00:06:20 Max now keep in mind we change the name
  • 00:06:23 of person not of second person and I do
  • 00:06:27 log second person here not first so
  • 00:06:29 adieu locked object which wasn't changed
  • 00:06:32 and yet we see the changed name so
  • 00:06:35 what's happening here well that simply
  • 00:06:38 happens because objects in JavaScript
  • 00:06:41 just like arrays
  • 00:06:42 which basically our objects are
  • 00:06:44 reference types let's take a closer look
  • 00:06:47 this is where we left to slide with our
  • 00:06:50 primitive values now before we come to
  • 00:06:53 the reference values it's important to
  • 00:06:54 understand where the primitive values
  • 00:06:56 are stored where the actual data is
  • 00:06:58 stored it has to be stored somewhere in
  • 00:07:00 our memory and it is stored on the stack
  • 00:07:02 now the stack as the name implies simply
  • 00:07:06 is a stack of data you could say in your
  • 00:07:09 memory and this is a type of memory
  • 00:07:11 which can be accessed really quick and
  • 00:07:13 which is very limited too it doesn't
  • 00:07:15 hold that much information it doesn't
  • 00:07:17 have that much space but due to the
  • 00:07:20 nature it is built or due to how it
  • 00:07:22 works it is very fast now reference
  • 00:07:25 types objects and as I said arrays which
  • 00:07:28 again are just objects kind of are
  • 00:07:31 stored on the heap now the heap is a
  • 00:07:34 different kind of place in memory
  • 00:07:36 unlike the stack the heap takes a little
  • 00:07:39 bit longer to be accessed but therefore
  • 00:07:42 it is able to hold much more information
  • 00:07:45 it's not as short living as the stack
  • 00:07:48 you could say and this type of memory is
  • 00:07:50 perfect for bigger amounts of data or
  • 00:07:52 data which changes frequently or
  • 00:07:54 dynamically that's a stack and to heap
  • 00:07:57 and it is this memory management which
  • 00:07:59 kind of dictates the behavior we saw
  • 00:08:01 before in the console let's understand
  • 00:08:04 how to stack works the stack holds as
  • 00:08:07 the name implies a stack of data let's
  • 00:08:09 say we already have some random number
  • 00:08:11 and some random text in there now we
  • 00:08:13 create a new variable first name max
  • 00:08:15 therefore we store this string max
  • 00:08:18 somewhere in memory or not somewhere
  • 00:08:20 actually on top of the stack and we
  • 00:08:22 basically know that this variable well
  • 00:08:25 is accessing this part of the stack this
  • 00:08:28 entry
  • 00:08:29 now if we assign this first name
  • 00:08:32 variable as a value to a new variable
  • 00:08:34 let's name it full name then a new entry
  • 00:08:38 is pushed on top of the stack and we
  • 00:08:39 know that this variable is referring to
  • 00:08:41 the topmost entry now so this is how we
  • 00:08:43 manage the stack or how data gets
  • 00:08:46 managed on the stack with you have our
  • 00:08:48 different data pieces and our variables
  • 00:08:51 know which position is stack they are
  • 00:08:54 referring to you could say
  • 00:08:55 and remember the stack is limited in
  • 00:08:58 space and therefore it is perfect for
  • 00:09:01 well that's where the name comes from
  • 00:09:02 primitive values like strings numbers
  • 00:09:04 which are in too complex which don't
  • 00:09:07 take up too much space let's take a look
  • 00:09:09 at the heat the heat works like this the
  • 00:09:12 green are just to heat that's a place in
  • 00:09:14 memory where elements are not stored on
  • 00:09:17 top of each other it's not managed like
  • 00:09:18 a stack it's managed randomly you could
  • 00:09:20 say but therefore each element has its
  • 00:09:23 own address and we still have to stack
  • 00:09:26 of course it's not a or solution we have
  • 00:09:29 different types of memory which are able
  • 00:09:31 to work together as you will see we now
  • 00:09:34 create a new object the employee one
  • 00:09:37 which is an object the following happens
  • 00:09:40 element is created in the heap which
  • 00:09:43 stores the actual object but we do have
  • 00:09:46 a pointer on the stack which stores the
  • 00:09:49 reference the address to this object in
  • 00:09:52 the heap and the variable simply stores
  • 00:09:55 the pointer and that's the interesting
  • 00:09:57 thing the variable doesn't know the
  • 00:10:00 address of the place in memory where our
  • 00:10:03 object is stored that's the difference
  • 00:10:05 to the previous approach but the
  • 00:10:08 variable knows where the pointer lies on
  • 00:10:10 the stack it knows the position of the
  • 00:10:12 pointer on the second the pointer in
  • 00:10:14 turn simply stores the address of the
  • 00:10:17 object in the heap now if we create a
  • 00:10:19 new variable employee queue and we store
  • 00:10:22 employee 1 as a value this creates a new
  • 00:10:25 pointer on the stack but and that is now
  • 00:10:28 the key thing this pointer points to the
  • 00:10:31 same place in memory as the first
  • 00:10:34 pointer did so therefore unlike the
  • 00:10:37 previous example where we managed
  • 00:10:38 primitive types on the stack if we
  • 00:10:41 assign the value to a new variable the
  • 00:10:44 actual value the object here is not
  • 00:10:47 copied the object still is the same it's
  • 00:10:50 only one place in memory but we do get a
  • 00:10:52 new pointer pointing to the same place
  • 00:10:55 and it's two different pointers which
  • 00:10:57 are stored in two different variables
  • 00:10:59 but pointing to the same value now if we
  • 00:11:02 go back to chase bin this is what
  • 00:11:05 explains where we see Chris here because
  • 00:11:08 when we assign
  • 00:11:09 as a value to second person the only
  • 00:11:12 thing we copied was the pointer but we
  • 00:11:14 still only had one place in memory
  • 00:11:17 therefore if I change this place a
  • 00:11:20 memory or change something about it the
  • 00:11:22 name here this gets changed for all the
  • 00:11:25 objects all the variables pointing to
  • 00:11:28 that place therefore also second person
  • 00:11:31 and I hope this is clear now why in this
  • 00:11:34 case when working with objects and again
  • 00:11:37 the same is true for arrays if we change
  • 00:11:40 it in one place it gets changed
  • 00:11:41 everywhere and every variable which
  • 00:11:43 points to the same place whereas when we
  • 00:11:46 work with primitive types strings
  • 00:11:48 boolean's and so on we get real copies
  • 00:11:52 now here are two important things I want
  • 00:11:54 to highlight if we create a new variable
  • 00:11:57 let's name it third-person because I'm
  • 00:11:59 very creative and this actually has the
  • 00:12:02 same value as the first person here so I
  • 00:12:06 just copied the object here in code and
  • 00:12:09 I could have typed that manually of
  • 00:12:11 course and we now log third person here
  • 00:12:15 and clear doesn't hit run the third
  • 00:12:18 person still has max and that is even
  • 00:12:21 true if I were to change or words you
  • 00:12:24 create that right after the first person
  • 00:12:27 here so third person is created right
  • 00:12:31 after the first person year is created
  • 00:12:33 and then we change the name of person
  • 00:12:36 and if I now hit clear and run again
  • 00:12:38 third person still has the name of Max
  • 00:12:41 and that's important this of course is a
  • 00:12:45 different place in memory because yet
  • 00:12:47 technically we know it it's the same
  • 00:12:50 object that does hold the same values
  • 00:12:52 but from a technical perspective if you
  • 00:12:55 understand how code works that gets
  • 00:12:58 executed at runtime of course your
  • 00:13:00 computer your browser doesn't know that
  • 00:13:02 these objects do hold the same content
  • 00:13:05 and even if the browser would recognize
  • 00:13:07 that it would still create two different
  • 00:13:10 objects at two different places on the
  • 00:13:12 heap because we're not copying any
  • 00:13:15 pointers here we have a brand new object
  • 00:13:17 so whenever we create a new object or a
  • 00:13:20 new array be that with the off
  • 00:13:22 literal notation he like here with the
  • 00:13:25 colleague braces or with the new keyword
  • 00:13:27 we get a new place in heap it's only
  • 00:13:30 that when we assign values like here
  • 00:13:33 where we store an old variable in a new
  • 00:13:35 one that we copy a pointer if we create
  • 00:13:38 a new object as here it always gets a
  • 00:13:41 new place in the heap so that's
  • 00:13:42 important to understand just because it
  • 00:13:44 looks identical here it doesn't make it
  • 00:13:46 identical still two different objects
  • 00:13:49 two different places in the heap that's
  • 00:13:52 the first important extra takeaway I
  • 00:13:54 wanted to add the other one is what if
  • 00:13:58 you really wanted to copy an object so
  • 00:14:00 here where we have persons of name
  • 00:14:02 equals Chris and then we influenced our
  • 00:14:06 second person because we assigned it
  • 00:14:08 here what if we really wanted to copy
  • 00:14:10 the person object here well we can do
  • 00:14:13 this by setting second person and I'm
  • 00:14:18 just going to comment this out here so
  • 00:14:20 that we have a brand new variable
  • 00:14:21 assignment so I can set second person
  • 00:14:24 equal to person to copy the pointer as
  • 00:14:27 you learned it but if you want to create
  • 00:14:30 a brand new object you can do this with
  • 00:14:32 the Bolton JavaScript object object and
  • 00:14:35 there the assign method which takes two
  • 00:14:37 arguments the first one is an empty
  • 00:14:40 object the second one is the one you
  • 00:14:42 want to copy that's a little trick
  • 00:14:44 object a sign is a built in method
  • 00:14:47 provided by JavaScript which allows you
  • 00:14:50 to create a new object and merge it with
  • 00:14:54 an existing one actually object design
  • 00:14:57 allows you to merge two objects into the
  • 00:15:00 first one and here since I pass an empty
  • 00:15:03 object that's the first argument which
  • 00:15:04 is the to be merged in object it creates
  • 00:15:07 a new one this one and merges the person
  • 00:15:10 object into it so it basically takes all
  • 00:15:13 the properties of the person object and
  • 00:15:15 merges it into second prizm now if we do
  • 00:15:18 this and we hit run you see that we got
  • 00:15:21 max all over the place because now the
  • 00:15:23 fact that we overwrite a name and your
  • 00:15:26 regional person object doesn't influence
  • 00:15:28 second person because you to using
  • 00:15:31 object assign we really copied it we
  • 00:15:34 created a new object and then copied the
  • 00:15:36 property
  • 00:15:36 of the old one there still is a god Cher
  • 00:15:40 you see that hobbies array in our object
  • 00:15:43 now if I not only change the name here
  • 00:15:46 personal name but I also change the
  • 00:15:50 hobbies let's say I push a new hobby on
  • 00:15:53 this array reading maybe if I now it
  • 00:15:58 clear and then run now you see that it
  • 00:16:03 again got changed here so here we're
  • 00:16:07 logging second person we again see that
  • 00:16:11 we get reading in this array even though
  • 00:16:14 I just told you that we now created a
  • 00:16:16 new object and copied all the properties
  • 00:16:18 and that is the issue remember that I
  • 00:16:22 told you that arrays are also reference
  • 00:16:24 types object assigned doesn't create a
  • 00:16:27 deep clone it doesn't create new objects
  • 00:16:32 of the properties it just creates a new
  • 00:16:34 object and copies the existing
  • 00:16:36 properties now since hobbies is an array
  • 00:16:39 and an array is a reference type it
  • 00:16:40 didn't create a new array and merge the
  • 00:16:44 old array into it it just took the old
  • 00:16:45 array so it took the pointer to the old
  • 00:16:47 array and merge that into our new object
  • 00:16:50 so even though we have a new object the
  • 00:16:53 properties if they are reference types
  • 00:16:56 still are the old ones so we still have
  • 00:16:58 the old array in the new object it's
  • 00:17:01 really getting confusing now right but I
  • 00:17:03 hope that this still makes sense arrays
  • 00:17:06 are reference types so even though we
  • 00:17:08 created a real copy of the object we
  • 00:17:11 didn't create one of the arrays element
  • 00:17:14 here deal arrays property now there is
  • 00:17:17 no super trivial solution to that there
  • 00:17:20 of course workarounds you could manually
  • 00:17:21 copy all the properties you could use a
  • 00:17:24 third-party library like lodash which
  • 00:17:27 offers you a clone deep function which
  • 00:17:29 does just that it allows you to deeply
  • 00:17:32 clone a value which means clone not just
  • 00:17:35 the object and then copy the properties
  • 00:17:37 but also really clone the properties to
  • 00:17:40 create new properties you could do that
  • 00:17:43 a link can be found in the video
  • 00:17:45 description
  • 00:17:46 but it's super important to be aware of
  • 00:17:48 this behavior and oftentimes it might
  • 00:17:50 not be an issue if it is well have a
  • 00:17:53 look at low – for example to find a
  • 00:17:55 quick and easy solution to that almost
  • 00:17:59 done one last thing what if you wanted
  • 00:18:02 to copy an array in a well way of
  • 00:18:06 creating a real copy just like with
  • 00:18:08 object assigned for an object how would
  • 00:18:10 you do that for an array well if you
  • 00:18:12 wanted to do that let me do that here at
  • 00:18:14 the very end let's say we have a new
  • 00:18:16 variable my hobbies then you could say
  • 00:18:19 equals person hobbies and that would be
  • 00:18:21 well just copying the pointer right the
  • 00:18:25 issue we already know so if I now log my
  • 00:18:27 hobbies here and I hit run we see sports
  • 00:18:32 cooking and reading but we'll see the
  • 00:18:35 very same thing if I do this before
  • 00:18:37 pushing the new value on person dot
  • 00:18:40 hobbies so if it wouldn't create a
  • 00:18:43 pointer if it would really create a real
  • 00:18:46 copy well we would expect to not see
  • 00:18:49 reading because we copy person hobbies
  • 00:18:52 before we push reading on it but of
  • 00:18:55 course what you will see is that if we
  • 00:18:56 hit run we see reading on the array
  • 00:18:58 again because it is a reference type now
  • 00:19:01 if we want to copy the real array we
  • 00:19:03 could do this for example by using slice
  • 00:19:05 the slice method is a built-in method
  • 00:19:08 offered by JavaScript which allows us to
  • 00:19:10 take a slice off the array and if you
  • 00:19:13 don't pass any arguments it will just
  • 00:19:14 take the full array and we'll create a
  • 00:19:17 new array based on that slice so it will
  • 00:19:20 create a new array and again they don't
  • 00:19:22 pass any arguments take all the elements
  • 00:19:24 of the old array and put them into the
  • 00:19:25 new one therefore if you now clear this
  • 00:19:28 a final time and hit run again now we
  • 00:19:31 only see sports and cooking because we
  • 00:19:33 copied the array before we pushed
  • 00:19:37 reading on it we made a real we created
  • 00:19:39 a real copy and not just copy it's the
  • 00:19:42 pointer and therefore now we have the
  • 00:19:46 array and look like at the point of time
  • 00:19:48 we did copy it your helps probably
  • 00:19:52 steaming now a lot of copying around a
  • 00:19:55 lot of console.log statements so I hope
  • 00:19:57 my point was clear but the
  • 00:20:00 different of reference and primitive
  • 00:20:02 types how you copy only the pointer if
  • 00:20:05 you assign a value which is a reference
  • 00:20:08 type and how you can still force the
  • 00:20:11 behavior of copying well making a real
  • 00:20:13 copy creating a new object or array with
  • 00:20:16 object assign or slice and then again
  • 00:20:20 still with the issue of not having a
  • 00:20:22 deep copy in the case of both ways
  • 00:20:25 actually slice an object assign which
  • 00:20:28 can be fixed with for example libraries
  • 00:20:31 like low – that's a little video about
  • 00:20:35 primitive and reference types and I hope
  • 00:20:37 it was helpful and could clear up some
  • 00:20:40 of the confusion and hopefully at least
  • 00:20:42 point you in the right direction of
  • 00:20:45 fixing this issue the next time you
  • 00:20:47 encounter some strange behavior when
  • 00:20:50 passing objects or arrays around in your
  • 00:20:52 code