자바스크립트/모던 자바스크립트 Deep Dive

원시 값과 객체의 비교

막이86 2023. 11. 15. 11:07
728x90

모던 자바스크립트 Deep Dive을 요약한 내용입니다.

  • 원시 타입과 객체 타입은 크게 세가지 측면에서 다른다.
    • 원시 값은 변경 불가능한 값이다. 객체는 변경 가능한 값이다.
    • 원시 값을 변수에 할당하면 변수에는 실제 값이 저장된다. 객체를 변수에 할당하면 변수에는 참조 값이 저장된다.
    • 원시 값을 갖는 변수에 다른 변수에 할당하면 원본의 원시 값이 복사되어 전달된다.(값에 의한 전달) 객체를 가르키는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달된다.(참조에 의한 전달)

11.1 원시 값

11.1.1 변경 불가능한 값

  • 원시 값은 변경 불가능한 값이다.
    • 한번 생성된 원시 값은 읽기 전용 값으로서 변경할 수 없다.
    • 변경 불가능하다는 것은 변수가 아니라 값에 대한 진술이다.
  • 원시 값은 변경 불가능하다는 말은 원시 값 자체를 변경할 수 없는 것이지 변수 값을 변경할 수 없다는 것이 아니다.
  • 변수의 상대 개념인 상수는 재할당이 금지된 변수를 말한다.
    • 상수도 값을 저장하기 위한 메모리 공간이 필요하므로 변수라고 할수 있다.
    • 상수는 단 한번만 할당이 허용되므로 변수 값을 변경 할 수 없다.
    • 상수는 재할당이 금지된 변수일 뿐이다.
    const o = {}
    o.a = 1
    console.log(o)   // {a: 1}
    
  • 원시 값은 변경 불가능한 값, 즉 읽기 전용 값이다.
    • 원시 값은 어떤 일이 있어도 불변한다.
  • 불변성을 갖는 원시 값을 할당한 변수는 재할당 이외에 변수 값을 변경할 수 있는 방법이 없다.

11.1.2 문자열과 불변성

  • 원시 값인 문자열은 다른 원시 값과 비교할 때 독득한 특징이 있다.
  • 문자열은 0개 이상의 문자로 이뤄진 집합을 말하며, 1개 문자는 2바이트의 메모리 공간에 저장된다.
  • 문자열은 몇개의 문자열로 이뤄 졌느냐에 따라 필요한 메모리 공강의 크기가 결정된다.
    • 숫자 값은 1도 1000000도 동일한 8바이트,
    • 문자열 값은 1개의 문자열은 2바이트 20개로 이뤄진 문자열은 20바이트
    var str1 = ''
    var str2 = 'Hello'
    
  • 문자열은 원시 타입이며, 변경 불가능하다.
  • 문자열은 유사 배열 객체이면서 이터러블이므로 배열과 유사하게 각 문자에 접근할 수 있다.
  • var str = 'string' console.log(str[0]) // s console.log(str.length) // 6 console.log(str.toUpperCase()) // STRING
  • 문자열의 일부 문자를 변경해도 반영되지 않는다.
    • 문자열은 변경 불가능한 값이기 때문
    • 한번 생성된 문자열은 읽기 전용 값으로서 변경할 수 없다.
    var str = 'string'
    str[0] = 'S'
    console.log(str)    // string
    
  • 변수에 새로운 문자열 재할당하는 것은 가능하다.
    • 기존 문자열을 변경하는 것이 아니라 새로운 문자열을 새롭게 할당하는 것이기 때문이다.

11.1.3 값에 의한 전달

  • 변수에 변수를 할당했을 때 무엇이 어떻게 전달되는가?
    • copy = score에서 score는 80으로 평가되고 copy도 80이 할당될 것이다.
    • 새로운 숫자 값 80이 생성되어 copy 변수에 할당 된다.
    var score = 80
    var copy = score
    
    console.log(score)      // 80
    console.log(copy)       // 80
    
    score = 100
    
    console.log(score)      // 100
    console.log(copy)       // 80
    
  • score 변수와 copy 변수는 숫자 값 80을 갖는다는 점에서 동일하다.
    • score 변수와 copy 변수의 값 80은 다른 메모리 공간에 저장된 별개의 값이다.
    var score = 80
    var copy = score
    
    console.log(score, copy)     // 80 80
    console.log(score === copy)  // true
    
  • score 변수와 copy 변수 값 80은 다른 메모리 공간에 저장된 별개이 값이라는 것에 주의하기 바란다.
    • score 변수의 값을 변경해도 copy 변수의 값에는 어떠한 영향도 주지 않는다.
    var score = 80
    var copy = score
    
    console.log(score, copy)     // 80 80
    console.log(score === copy)  // true
    
    score = 100
    console.log(score, copy)     // 100 80
    console.log(score === copy)  // false
    
  • 두 변수의 원시 값은 서로 다른 메모리 공간에 저장된 별개의 값이 되어 어느 한쪽에서 재할당을 통해 값을 변경하더라도 서로 간섭할 수 없다.

11.2 객체

  • 객체는 프로퍼티의 개수가 저애져 있지 않으며, 동적으로 추가되고 삭제할 수 있다.
  • 프로퍼티의 값에 대한 제약이 없다.
  • 객체는 복합적인 자료구조이므로 객체를 관리하는 방식이 원시 값과 비교해서 복잡하고 구현 방식도 브라우저 제조사마다 다를 수 있다.
  • 객체를 생성하고 프로퍼티에 접근하는 것도 원시 값과 비교할 때 비용이 많이 드는 일이다.
  • 객체는 원시 값과는 다른 방식으로 동작하도록 설계되엉 ㅣㅆ다.

11.2.1 변경 가능한 값

  • 객체 타입의 값은 변경 가능한 값이다.
  • 원시 값을 할당한 변수는 원시 값 자체를 값으로 갖는다. 하지만 객체를 할당한 변수가 기억하는 메모리 주소를 통해 메모리 공간에 접근하면 참조 값에 접근할 수 있다.
  • 객체를 할당한 변수를 참조하면 메모리에 저장되어 있는 참조 값을 통해 실제 객체에 접근한다.
  • var person = { name: 'Lee' } console.log(person) // {name: 'Lee'}
  • 원시 값은 변경 불가능한 값으로 원시 값을 갖는 변수의 값을 변경하려면 재할당 외에는 방법이 없다.
    • 객체를 할당한 변수는 재할당 없이 객체를 직접 변경할 수 있다.
    • 재할당 없이 프로퍼티를 동적으로 추가할 수 있고 프로퍼티 값을 갱신할 수 있으며 프로퍼티 자체를 삭제할 수 있다.
    var person = {
    	name: 'Lee'
    }
    person.name = 'Kim'
    person.address = 'seoul'
    
    console.log(person) // {name: 'Kim', address: 'seoul'}
    
  • 메모리의 효율을 위해 객체를 복사해 생성하는 비용을 절약하여 성능을 향상시키기 위해 객체는 변경 가능한 값으로 설계되었다.
    • 원시 값과 다르게 여러 개의 식별자가 하나의 객체를 공유할 수 있는 부작용이 있다.

11.2.2 참조에 의한 전달

  • 여러 개의 식별자가 하나의 객체를 공유할 수 있다는 것이 무엇을 의미하는지, 이로 인해 어떤 부작용이 발생하는지 확인해보자.
    • 두 개의 식별자가 하나의 객체를 공유한다.
    • 원본 또는 사본 중 어느 한쪽에서 객체를 변경하면 서로 영향을 주고 받는다.
    var person = {
    	name: 'Lee'
    }
    
    var copy = person
    console.log(copy === person)  // true
    
    copy.name = 'Kim'
    person.address = 'Seoul'
    
    console.log(person)           // {name: 'Kim', address: 'Seoul'}
    console.log(copy)             // {name: 'Kim', address: 'Seoul'}
    
  • === 연산자는 변수에 저장되어 있는 값을 타입 변환하지 않고 비교한다.
    • 객체를 할당한 변수를 비교하면 참조 값을 비교
      • person1, person2 변수가 가리키는 객체는 내용은 같지만 다른 메모리에 저장된 별개의 객체
      • 변수의 참조 값은 전혀 다른 값
    • 원시 값을 할당한 변수를 비교하면 원시 값을 비교
      • person1.name, person2.name은 값으로 평가될 수 있는 표현식이다.
    var person1 = {
    	name: 'Lee'
    }
    
    var person2 = {
    	name: 'Lee'
    }
    
    console.log(person1 === person2)            // false
    console.log(person1.name === person2.name)  // true
    
728x90

'자바스크립트 > 모던 자바스크립트 Deep Dive' 카테고리의 다른 글

전역 변수의 문제점  (1) 2023.11.15
스코프  (0) 2023.11.15
함수  (1) 2023.11.15
객체 리터럴  (0) 2023.11.15
타입 변환과 단축 평가  (0) 2023.11.15