console.log

[모던 자바스크립트 Deep Dive] 16 - 18 장 본문

개발공부/JavaScript

[모던 자바스크립트 Deep Dive] 16 - 18 장

foresight 2023. 8. 22. 15:21

16. 프로퍼티 어트리뷰트

내부 슬롯과 내부 메서드

  • ECMAScript에서 사용하는 이중 대괄호 [[…]]
  • 개발자가 직접 접근할 수 없는 내부 로직
  • 일부 간접적으로 접근 가능한 수단 제공 ——> [[Prototype]] : _ proto _

프로퍼티 어트리뷰트와 디스크립터 객체

  • 프로퍼티 어트리뷰트
    • 프로퍼티의 상태를 나타내는 값
    • 프로퍼티 생성 시 자동 정의
    • 프로퍼티의 값, 값의 갱신 가능 여부, 열거 가능 여부, 재정의 가능 여부
    • [[Value]], [[Writable]], [[Enumerable]], [[Configurable]] —→ Object.getOwnPropertyDescriptor로 간접 접근 가능
  • Object.getOwnPropertyDescriptor
    • 첫 번째 매개변수 : 객체의 참조
    • 두 번째 매개변수 : 프로퍼티 키
    • Object.getOwnPropertyDescriptor(person, 'name');
    • 반환값 : 하나의 프로퍼티에 대한 프로퍼티 디스크립터 객체 or undefined
    • ES8에서는 모든 프로퍼티의 상태정보를 제공하는 프로퍼티 디스크립터 객체들 반환

데이터 프로퍼티와 접근자 프로퍼티

  • 데이터 프로퍼티
    • 키와 값으로 구성된 일반적인 프로퍼티
    • 프로퍼티 어트리뷰트
      • [[Value]] : 프로퍼티 값에 접근하면 반환하는 값
      • [[Writable]] : 값의 변경 가능 여부, boolean 값 (default : true)
      • [[Enumerable]] : 열거 가능 여부, boolean 값 (default : true)
      • [[Configurable]] : 재정의 가능 여부, boolean 값 (default : true)
  • 접근자 프로퍼티
    • 자체적으로 값을 갖지 않고 다른 프로퍼티의 값을 읽거나 접근자 함수로 구성된 프로퍼티
    • 프로퍼티 어트리뷰트
      • [[Get]] : 프로퍼티 값에 접근 —> getter 함수 호출 (접근자 함수) —> 값 반환
      • [[Set]] : 프로퍼티 값 저장 —> setter 함수 호출 (접근자 함수) —> 값 저장
      • [[Enumerable]] : 열거 가능 여부, boolean 값 (default : true)
      • [[Configurable]] : 재정의 가능 여부, boolean 값 (default : true)
  • 구분 방법
    • 일반 객체의 _ _ proto _ _ : 접근자 프로퍼티
    • 함수 객체의 _ _ proto _ _ : 데이터 프로퍼티
    • 즉, Object.getOwnPropertyDescriptor 가 반환한 객체를 보고 판단

프로퍼티 정의

  • Object.defineProperty 를 통해 프로퍼티 어트리뷰트 정의
    • 첫 번째 매개변수 : 객체의 참조
    • 두 번째 매개변수 : 프로퍼티 키
    • 세 번째 매개변수 : 프로퍼티 디스크립터 객체
    • Object.defineProperty : 한 번에 하나 정의
    • Object.defineProperties : 여러 개 한 번에 정의
    • 초기값
      • value : [[Value]] : undefined
      • get : [[Get]] : undefined
      • set : [[Set]] : undefined
      • writable : [[Writable]] : flase
      • enumerable : [[Enumerable]] : flase
      • configurable : [[Configurable]] : flase

객체 변경 방지

  • 객체는 변경 가능한 값, 재할당 없이 직접 변경 가능
  • 프로퍼티 추가 및 삭제, 갱신, 프로퍼티 어트리뷰트 재정의
  • 객체 변경 방지 메서드
    구분 메서드 프로퍼티 추가 프로퍼티 삭제 프로퍼티 값 읽기 프로퍼티 값 갱신 프로퍼티 어트리뷰트 재정의
    객체 확장 금지 Object.preventExtensions
    객체 밀봉 Object.seal
    객체 동결 Object.freeze
  • 위 세가지 메서드는 얕은 변경 방지로 중첩된 객체에는 영향을 미치지 않음

17. 생성자 함수에 의한 객체 생성

Object 생성자 함수

  • new : 빈 객체 생성 —> 프로퍼티, 메서드 추가
  • 그다지 유용하지 않음 …

생성자 함수

  • 객체 리터럴에 의한 객체 생성 방식의 문제점
    • 단 하나의 객체만 생성
    • 구조가 동일함에도 불구하고 매번 같은 프로퍼티와 메서드 기술해야함
  • 생성자 함수에 의한 객체 생성 방식의 장점
    • 템플릿처럼 생성자 함수를 사용해 구조가 종일한 객체 여러 개를 간편하게 생성
    • new 와 함께 함수를 호출하면 생성자 함수로 동작
  • 생성자 함수의 인스턴스 생성 과정
    • 인스턴스 생성 - 필수
    • 인스턴스 초기화 - 옵션 (전달받은 매개변수)
    1. 인스턴스 생성과 this 바인딩 : 암묵적으로 빈 객체 생성 후 this 바인딩
    2. 인스턴스 초기화 : this에 바인딩되어 있는 객체에 프로퍼티나 메서드 추가 → 매개변수로 초기화 or 할당
    3. 인스턴스 반환 : 생성자 함수 내부의 모든 처리가 끝나면 this(혹은 return 객체)가 암묵적으로 반환됨
  • 내부 메서드
    • 함수 객체는 일반 객체의 내부 슬롯과 내부 메서드를 모두 가지고 있음
    • [[Call]] : 일반 함수로 호출 시 (callable) —> 모든 함수 객체는 반드시 callable
    • [[Construct]] : new 와 함께 생성자 함수로 호출 시 (constructor)
      • constructor : 함수 선언문, 함수 표현식, 클래스
      • non-constructor : 메서드(ES6 메서드 축약 표현), 화살표 함수
  • new 연산자
    • [new.target](http://new.target) 을 통해 생성자 함수로서 호출되었는지 확인
    • 함수 본인을 가리킴
    • 만약 일반 함수로 호출되었을 경우 undefined
    • Object, Function 생성자 함수는 new, new 없이 호출 시 동일하게 동작
    • String, Number, Boolean 생성자 함수는 new와 함께 호출 시 객체 생성 후 반환, new 없이 호출 하면 해당 값을 반환

18. 함수와 일급 객체

일급 객체

  • 무명의 리터럴로 생성 가능 (런타임에 생성 가능)
  • 변수, 자료구조(객체, 배열)에 저장 가능
  • 함수의 매개변수에 전달 가능
  • 함수의 반환값으로 사용 가능
  • 자바스크립트의 함수는 위 모든 조건을 만족
    • 함수가 일급객체라는 것은 객체와 동일하게 사용 가능하다는 의미다.
    • 함수는 값을 사용할 수 있는 모든 곳에 리터럴로 정의할 수 있다.
    • 런타임에 함수 객체로 평가된다.
    • 함수의 반환값, 매개변수에 사용 가능하다.
    • 함수는 호출가능 !!!!

함수 객체의 프로퍼티

  • console.dir 을 통해 함수 객체의 프로퍼티 확인 가능
  • getOwnPropertyDescriptor 메서드로 프로퍼티 어트리뷰트 확인 가능
  • 종류
    • arguments
      • 전달된 인수들의 정보를 담은 유사 배열 객체
      • 함수 내부에서만 사용 가능
      • ES3부터 표준에서 폐지됨 —→ 함수 내부에서 arguments객체 참조 권장
      • 매개변수 개수와 달라도 상관없음 (이때 초과된 인수가 arguments 객체의 프로퍼티로 저장됨)
      • 가변 인자 함수를 구현할 때 용이
      • ES6에서 Rest 파라미터 도입됨 ! !
    • caller
      • 비표준 프로퍼티 … 이후에도 표준화될 예정 없음 몰라도 됨 ~~~~~~!!!!!!
    • length
      • 선언한 매개변수의 개수
      • arguments의 length와 다를 수 있음 !
    • name
      • 함수 이름
      • ES6에서 정식 표준으로 됨
      • ES5 : 빈 문자열을 값으로 가짐
      • ES6 : 함수 객체를 가리키는 식별자를 값으로 가짐
      • 함수 이름과 함수 객체를 가리키는 식별자는 의미가 다름 주의 !!!
    • prototype
      • constructor만이 소유하는 프로퍼티
      • 생성자 함수로 호출될 때 생성할 인스턴스의 프로토타입 객체를 가리킴
    • _ _ proto _ _ : 접근자 프로퍼티이며 Object.prototype 프로퍼티 상속받은 것임
      • 내부 슬롯이 가리키는 프로토타입 객체에 접근하기 위해 사용 (간접 접근)