[JS] 원시 값과 객체의 비교

Jay ·2022년 11월 9일
0

brainstorming

. Javascript는 call by reference 인가 call by value인가?
. call by sharing?
. 상수? 상수(const)는 immutable 한가?
. 얕은 복사와 깊은 복사?
. 불변성이란?
. '=='와 '==='의 차이

원시 값과 객체의 비교

Javascript에서 데이타 타입은 크게 원시 타입(Primitive)과 객체 타입(object/reference)로 구분 가능.

primitive와 object의 차이점

  • 원시타입은 immutable하고 객체는 mutable.
  • 원시 값을 변수에 할당하면 실제 값이 저장, 객체는 참조 값이 저장.
  • 원시 값을 가진 변수를 다른 변수에 할당하면 원시 값이 복사되어 전달되지만(pass by value), 객체는 원본의 참조 값이 복사되어 전달된다(pass by reference).

1. 원시 값

1.1 변경 불가능한 값

Immutable value. 변경 불가능한 값. 읽기전용.

상수?

재할당이 금지된 변수.

1.2 문자열과 불변성

원시 값을 저장하려면 먼저 확보해야 하는 메모리 공간의 크기를 결정해야 한다.
(문자열-2bye, 숫자-8byte 이외에는 브라우저 마다 원시타입의 크기 상이)

자바스크립트는 '문자'를 위한 데이터 타입만을 제공하는 C, 자바와 달리 '문자열' 원시 타입을 따로 제공한다.

이는 문자열이 생성된 이후에는 변경할 수 없음을 의미.

문자열은 유사 배열 객체이면서 이터러블이므로 배열과 유사하게 각 문자에 접근가능. (래퍼 객체)

유사 배열(Array-like) 객체

유사 배열 객체란 마치 배열처럼 인덱스로 프로퍼티 값에 접근할 수 있고 length 프로퍼티를 갖는 객체를 말한다.

  • 인덱스를 통해 각 문자에 접근가능.
  • length 프로퍼티를 가지므로 for문으로 순회가능.

래퍼(Wrapper) 객체

원시 값인데도 생성자 함수가 존재?

마침표(또는 대괄호)접근법으로 접근하면 자바스크립트 엔진이 원시값을 연관된 객체로 변환해주고, 처리가 끝난 이후 객체는 가비지 컬렉터로 처리하여 원시값으로 되돌린다.

문자열, 숫자, 불리언, 심벌은 암묵적으로 생성되는 래퍼 객체에 의해 마치 객체처럼 사용 가능.

new 연산자를 사용해 String, Number 등을 생성하는 것은 불필요하며 권장되지도 않음.

1.3 값에 의한 전달?

원시값 변수를 할당하면 원시 값이 복사되어 전달.
= 값에 의한 전달.

하지만 엄밀히 말하면 '공유에 의한 전달(pass by sharing)'.

변수에는 값이 아니라 메모리 주소가 전달되기 때문.

따라서 '값에 의한 전달'도 사실은 값을 전달하는 것이 아닌 메모리 주소를 전달한다. 단, 전달된 메모리 주소를 통해 메모리 공간에 접근하면 값을 참조할 수 있다.

2. 객체

브라우저마다 객체의 메모리 확보방식, 관리 방법은 상이.
향상된 해시테이블 방식으로 구현.

프로토타입 기반의 자바스크립트의 객체는 일반적인 클래스 객체보다 동적으로 프로퍼티와 메서드를 추가하는 데에 있어 자유롭지만, 이론적으로 성능면에서는 객체 생성과 프로퍼티 접근에 비용이 더 들어간다.
하지만 자바스크립트는 '히든 클래스' 라는 방식을 사용해 다른 언어만큼의 빠른 속도를 보장한다.

2.1 변경 가능한 값

mutable value.

객체를 원시 값처럼 복사하고 새로 생성하면 명확하고 신뢰성이 확보될 수 있지만, 비용이 많이 들기 때문에 비효율적.

따라서 객체는 변경 가능한 값으로 설계됨.

하지만, 그렇기 때문에 여러 개의 식별자가 하나의 객체를 공유할 수 있다는 단점이 존재.

얕은 복사와 깊은 복사

2.2 참조에 의한 전달 ?

변수에 저장되어 있는 값이 원시 값이냐, 참조 값이냐의 차이가 있을뿐 모두 값임.

따라서, 자바스크립트에는 '참조에 의한 전달'은 존재하지 않고 '값에 의한 전달'만이 존재한다고 말할 수 있다.

이를 '공유에 의한 전달'이라고 부르기도 하나 정확한 명칭은 아님.

let person1 = {
  name: 'Lee'
}
let perseon2 = {
  name: 'Lee'
};

console.log(person1 === perseon2)
console.log(person1.name === person2.name)
profile
Jay입니다.

0개의 댓글