1
00:00:01,200 --> 00:00:02,510
Here's a student.

2
00:00:02,535 --> 00:00:09,848
You want a copy to work with, so you assign the student to a new variable and change the name on the copy to Thomas.

3
00:00:09,931 --> 00:00:13,214
The copy's name is Thomas, as you wanted.

4
00:00:13,356 --> 00:00:19,612
But the student's name is also Thomas now, and you never touched the student.

5
00:00:20,312 --> 00:00:24,211
To see why, let's start with what an object is.

6
00:00:24,341 --> 00:00:33,789
An object is a collection of data, which we call properties, and functions, which we call methods, in a single package.

7
00:00:33,930 --> 00:00:44,110
As an example, here's a student object, with a name, a favorite color, and a home address that is itself another object.

8
00:00:44,310 --> 00:00:47,849
There are two ways to access parts of an object.

9
00:00:48,048 --> 00:00:52,725
The first is dot notation, just like Java and Python.

10
00:00:53,110 --> 00:00:58,043
JavaScript also supports bracket notation, which is like an array.

11
00:00:58,242 --> 00:01:06,530
This approach is quite useful, and you need it when the name you want is held in a variable, or when it has a hyphen in it.

12
00:01:06,834 --> 00:01:10,222
You can add or delete a property at any time.

13
00:01:10,433 --> 00:01:19,394
When you ask for something that isn't there, JavaScript is permissive: you just get undefined, rather than an error.

14
00:01:19,594 --> 00:01:23,992
There is a wrinkle when you go more than one level at a time.

15
00:01:24,284 --> 00:01:30,076
The first access might return undefined, and the next step is an error.

16
00:01:30,368 --> 00:01:41,813
For example, ask for a number on a phone property that's not in the object, and you'll get a type error, because you're reading a property of undefined.

17
00:01:41,896 --> 00:01:51,148
The question mark dot operator can help, as it stops before that and returns undefined instead.

18
00:01:51,848 --> 00:01:55,039
Now for a point that often catches people.

19
00:01:55,180 --> 00:01:59,950
When you assign and change values, the behavior depends on the type.

20
00:02:00,091 --> 00:02:03,085
Numbers and strings are primitive types.

21
00:02:03,168 --> 00:02:07,542
Assign a number to a second variable, and you get a second value.

22
00:02:07,753 --> 00:02:12,581
Change one, and the other stays as it was.

23
00:02:12,781 --> 00:02:17,771
Objects, arrays and functions in JavaScript are reference types.

24
00:02:17,913 --> 00:02:21,939
Since they can be large, the variable doesn't hold the data.

25
00:02:22,243 --> 00:02:24,784
It holds a reference to the value.

26
00:02:24,995 --> 00:02:32,539
So assigning student to a second variable copies the reference to the object, and not the object itself.

27
00:02:32,750 --> 00:02:36,219
You now have two names for one object.

28
00:02:36,616 --> 00:02:41,084
Change the name through either one, and both see the change.

29
00:02:41,388 --> 00:02:44,102
That's what happened to our student.

30
00:02:44,303 --> 00:02:49,572
You might expect declaring the object with const to prevent this, but it doesn't.

31
00:02:49,713 --> 00:02:54,437
Const only stops the variable from being assigned a different value.

32
00:02:54,740 --> 00:02:58,082
The object it refers to can still change.

33
00:02:58,165 --> 00:03:01,948
If you want to stop that, use Object.freeze.

34
00:03:02,031 --> 00:03:07,300
Changes to a frozen object are ignored, or they're an error in strict mode.

35
00:03:07,511 --> 00:03:13,581
It only freezes the one level, though, so the address inside can still change.

36
00:03:14,282 --> 00:03:22,094
The differences between primitives and reference types are significant, and they even change what equal means.

37
00:03:22,490 --> 00:03:34,006
Even if two individual objects have the same contents, they are two distinct objects, so comparing them is false, with double equals or with triple equals.

38
00:03:34,089 --> 00:03:39,753
The comparison is true only when both variables refer to the same object.

39
00:03:40,056 --> 00:03:49,180
JavaScript has no operator that compares objects by their contents, though you could write a function to do this yourself if needed.

40
00:03:49,879 --> 00:03:53,929
The same reference type issues apply when you call a function.

41
00:03:54,233 --> 00:03:57,993
The parameter gets a copy of what the variable holds.

42
00:03:58,134 --> 00:04:06,689
For an object, that's a copy of the reference to the object, so the function can change the object, and the caller will see the change.

43
00:04:06,899 --> 00:04:12,644
You'll hear this called pass by reference, though the reference itself was copied.

44
00:04:12,948 --> 00:04:16,267
Compare this to when we pass a primitive type.

45
00:04:16,571 --> 00:04:21,457
If you change it in the function, the value isn't changed outside.

46
00:04:21,482 --> 00:04:23,279
This is pass by value.

47
00:04:23,421 --> 00:04:29,874
Note that even though a function can change an object's properties, it can't replace the caller's object.

48
00:04:30,178 --> 00:04:35,783
Assign a new object to the parameter, and only the local name changes.

49
00:04:36,483 --> 00:04:40,301
If you want a second object, you need to make a copy.

50
00:04:40,512 --> 00:04:47,232
The usual way to accomplish this is spread, three dots inside a new object literal.

51
00:04:47,373 --> 00:04:50,459
It copies each property into the new object.

52
00:04:50,600 --> 00:04:55,660
Change the copy's name, and you are just affecting the new object.

53
00:04:55,743 --> 00:04:58,934
The original object stays the same.

54
00:04:59,135 --> 00:05:00,619
But be careful.

55
00:05:00,830 --> 00:05:03,893
In our example, look at the address.

56
00:05:03,976 --> 00:05:08,827
That property held a reference, so the reference is what got copied.

57
00:05:09,224 --> 00:05:14,237
Change the city through the copy, and the original's city changes too.

58
00:05:14,634 --> 00:05:19,450
This is called a shallow copy, because it goes one level deep.

59
00:05:19,651 --> 00:05:23,028
For a deep copy, use structuredClone.

60
00:05:23,053 --> 00:05:25,628
It copies the nested objects too.

61
00:05:25,932 --> 00:05:31,747
It only works on data, though, and it throws an error on functions.

62
00:05:32,447 --> 00:05:35,011
You don't free objects yourself.

63
00:05:35,408 --> 00:05:43,010
JavaScript has a garbage collector, and an object stays as long as your program can reach it.

64
00:05:43,210 --> 00:05:47,875
Setting a variable to null can indicate you are done with something.

65
00:05:48,272 --> 00:05:53,878
When the last reference is gone, the object can be collected, and the memory freed.

66
00:05:54,274 --> 00:05:59,369
If you hold on to references you no longer need, you leak memory.

67
00:05:59,673 --> 00:06:05,476
In JavaScript we need to be especially careful with timers and event handlers.

68
00:06:06,176 --> 00:06:09,936
So when an object surprises you, follow the references.

69
00:06:10,077 --> 00:06:12,445
Who else is pointing at this object?

70
00:06:12,445 --> 00:06:15,532
Is this a copy, or another name?

71
00:06:15,732 --> 00:06:22,127
To explore these ideas further, try the playgrounds on the Objects and Arrays page.

72
00:06:22,338 --> 00:06:27,038
Methods, and the keyword this, get a film of their own.
