원시 값을 갖는 변수를 다른 변수에 할당하면 원본의 원시 값이 복사되어 전달 => 값에 의한 전달(pass by value)
객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달 => 참조에 의한 전달(pass by reference)
원시 값
변경 불가능한 값(immutable value)
읽기 전용 값
원시 값은 어떤 일이 있어도 불변하기 때문에 데이터의 신뢰성을 보장함
값을 직접 변경할 수 없기 때문에 변수 값을 재할당하면 새로운 메모리 공간을 확보하고 변수가 참조하던 메모리 공간의 주소를 변경
불변성을 가짐 => 재할당 이외에 변수 값을 변경할 수 있는 방법은 없음
문자열
문자열은 다른 원시값과 달리 몇 개의 문자로 이뤄졌느냐에 따라 필요한 메모리 공간의 크기가 결정됨
자바스크립트는 개발자의 편의를 위해 문자열 타입을 원시타입으로 제공
즉, 문자열이 생성된 이후에는 변경할 수 없음
따라서 예기치 못한 변경으로부터 자유로워 데이터의 신뢰성을 보장함
C는 char타입만 있고, 문자열은 배열로 처리, Java는 String 객체로 문자열 처리
자바스크립트의 문자열은 유사 배열 객체이면서 이터러블임
유사 배열 객체 : 마치 배열처럼 인덱스로 프로퍼티 값에 접근할 수 있고 length 프로퍼티를 갖는 객체. (원시 값을 객체처럼 사용하면 원시 값을 감싸는 래퍼 객체로 자동 변환됨)
다른 원시 타입 처럼 값을 변경하는 것이 아니라 재할당 시 새로운 문자열을 새롭게 할당
인덱스로 접근해 문자열의 일부 문자를 변경해도 반영되지 않음
값에 의한 전달
var score = 80;
var copy = score;
score = 100;
변수에 원시 값을 갖는 변수를 할당하면 할당받는 변수(copy)에 할당되는 변수(score)의 원시 값이 복사되어 전달됨
score 변수와 copy 변수의 값 80은 메모리 공간에 저장된 별개의 값임
따라서 score 변수의 값을 변경해도 copy 변수의 값에는 어떠한 영향도 주지 않음
값의 이한 전달도 사실은 값을 전달하는 것이 아니라 메모리 주소를 전달함
객체
프로퍼티의 개수가 정해져 있지 않으며 동적으로 추가, 삭제 가능.
프로퍼티의 값에 제약 없음
원시 값과 달리 확보해야 할 메모리 공간의 크기를 사전에 정할 수 없음
복합적인 자료구조
자바스크립트는 Java, C++과는 달리 클래스 없이 객체를 생성할 수 있고 객체 생성 이후에도 동적으로 프로퍼티와 메서드를 추가할 수 있어 사용하기에 편리하지만 클래스 기반 객체지향 프로그래밍 언어의 객체보다 생성과 프로퍼티 접근에 비용이 더 많이 드는 비효율적인 방식임
크롬 V8 자바스크립트 엔진은 프로퍼티에 접근하기 위해 히든 클래스 방식을 사용함
변경 가능한 값
객체는 변경 가능한 값(mutable value)
객체를 할당한 변수가 기억하는 메모리 주소를 통해 메모리 공간에 접근하면 참조 값에 접근 가능함.
객체를 할당한 변수는 재할당 없이 객체를 직접 변경 가능함
즉, 재할당 없이 프로퍼티를 동적으로 추가할 수 있고 프로퍼티 값을 갱신할 수 있으며 프로퍼티 자체를 삭제 가능함
메모리에 저장된 객체를 직접 수정 가능함
객체를 할당한 변수에 재할당을 하지 않았으므로 객체를 할당한 변수의 참조 값은 변경되지 않음
메모리를 효율적으로 사용하기 위해, 객체를 복사해 생성하는 비용을 절약해 성능을 향상시키기 위해 객체는 변경 가능한 값으로 설계되어 있음
하지만 여러 개의 식별자가 하나의 객체를 공유할 수 있다는 단점이 잇음
얕은 복사 vs 깊은 복사
얕은 복사
한 단계까지만 복사하는 것
깊은 복사
객체에 중첩되어 있는 개체까지 모두 복사
즉, 원시값처럼 완전한 복사본을 만듦
참조에 의한 전달
var person = {
name : 'lee'
};
var copy = person;
객체를 가리키는 변수(person)을 다른 변수(copy)에 할당하면 원본의 참조 값이 복사되어 전달됨