
변경 불가능한 값이다.
변수에는 실제값이 저장되며, 복사하면 값 자체가 복사된다. 쉽게 말하면 일반 값이다.
ex) string, number, boolean, null, undefined, symbol
변경 가능한 값이다.
변수에는 실제 객체 자체가 들어가는 게 아니라, 그 객체를 가리키는 참조값이 저장된다. 그래서 복사하면 객체 자체가 복사되는 게 아니라 참조값이 복사된다.
ex) object, array, function, Map, Set
배열도 객체이기 때문에 안에 값들에 접근할 수 있고, 각 요소의 참조를 바꾸는 방식으로 동작한다. 그래서 array.sort() 같은 메서드를 통해 값 자체를 바꾸지 않고 참조 순서를 바꿔 정렬할 수 있다.

왼쪽은 배열(객체), 오른쪽은 값들(원시값), 화살표는 참조라고 보면 된다.
오른쪽 값 자체는 그대로 두고, 배열이 어떤 값을 가리키고 있는지(화살표)를 바꿔서 순서를 바꿀 수 있다.
즉, 값들은 변하지 않았는데 배열 안에서 참조 순서가 바뀌면서 정렬된 것처럼 보인다.

이 그림의 경우, 605번지의 지훈은 그대로 있는데, myClass[0]이 원래 104를 가리키다가 605를 가리키게 바꾸면 0번이 지훈을 가리키게 된다.
그래서 배열 안에 있는 참조값(주소)만 바꿔도 정렬 결과가 달라질(바뀔) 수 있다. 실제로 605번지에 있는 지훈 자체가 바뀐 것은 아니다.
원시값에도 메서드를 쓸 수 있을까?
const name = "오다현"
name은 string이고 원시값이다. 그런데도 name.toUpperCase()같은 메서드를 사용할 수 있다. 객체가 아닌데 어떻게 가능할까?
그 이유는 래퍼 객체 때문이다.
js에서는 원시값에 메서드를 사용하려고 하면, 그 순간 객체처럼 감싸서 처리한다. 그래서 string 원시값이여도 문자열 메서드를 사용할 수 있다.
배열은 객체다. 그럼 배열 안에 있는 값은 뭘까?
배열 자체는 객체다.
하지만 배열 안에 들어 있는 값은 타입에 따라 다르다. number, string, null, symbol 등은 원시값이다. 근데 배열안에는 객체 또는 배열이다.
즉, 배열은 객체지만 배열 안의 요소는 원시값일 수도 있고 객체일 수도 있다.