딥다이브 스터디 16, 17, 18(프로퍼티 어트리뷰트, 생성자 함수에 의한 객체생성, 일급객체)

김영현·2023년 10월 4일
0

프로퍼티 어트리뷰트

두개의 개념을 먼저 살펴본다.

  • 내부 슬롯
  • 내부 메서드

JS엔진 내부에 존재하는 프로퍼티와 메서드다.
보통 [[Something]] 이렇게 이중대괄호로 감싸져있다.
원칙적으로 은닉화 시킨 녀석들이다. 일부는 특별한 접근자를 제공하여 접근 가능하다.
=> 모든 객체가 지닌 [[Prototype]]__proto__getPrototypeOf()로 접근 가능하다. 후자는 read-only

프로퍼티

프로퍼티를 생성하면 내부슬롯으로 프로퍼티 어트리뷰트(속성)을 기본값으로 정의한다.

영어를 할줄 알면 옵션을 알 수있다.
순서대로 , 쓰기 가능, 열거 가능, 정의 가능. 기본적으로 true구나.
이러한 프로퍼티를 data property라고함. 용어까진 외울 필요 없을듯...
이런 것들이 있다는 것만 알고 넘어가자.

access property에는 get, set, enumerable, configurable이 있다.
각각 값 가져오기, 값 설정하기, 열거하기, 재정의하기.
get프로토타입 체인을 타고 쭉 간다.

이러한 프로퍼티들을 생성시에 동적으로 설정할수도 있다.

값은 존재하지만, 순회가 되지않고 쓰기, 재정의가 되지 않는다.
에러가 발생하지 않는 게 특이점.


객체 변경방지

사실, 이게 프로퍼티 어트리뷰트의 주 내용중 하나다.
객체는 불변해야한다. 하지만, 객체 내부값들은 변경 가능하다.
이를 방지하기 위하여 바로 전에 사용한 Object.defineProperty()를 사용할수도있지만...
더 다양한 메서드들이 있다.

불변객체 관련 메서드

  • Object.preventExtensions() : 객체확장 금지.
  • Object.seal() : 객체를 밀봉. 정확히 말하자면 추가, 삭제, 재정의금지. => 읽기쓰기 가능
  • Object.freeze() : 읽기만 가능!

하지만 놀랍게도...위의 세 메서드는 shallow only다. 즉, 중첩 객체에는 적용 안됨.
=> 재귀적으로 Object.assgin()을 사용했던것 처럼, 재귀적으로 하면 된다.


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

10장 객체부분에서 설명한 생성자 함수를 이용한 객체 생성을 알아보자.
Object, String, Number...등 다양한 생성자 함수가 있다.

const obj = new Object();
const str = new String("kim");
const num = new Number(5);
...

리터럴{}, "kim", 5방식보다 귀찮아보인다.
왜 사용하는 걸까?

이전 설명 글을 보면된다.
보충 : new.target이 지원되지 않는 버전(es6이전)이라면 instanceOf를 사용하면 된다.

참고로 함수도 결국 객체기에 내부슬롯을 가지고있다.
그냥 함수로 호출되면 [[Call]이 호출되고, 생성자 함수로 호출되면 [[Construct]]가 호출된다.


함수와 일급 객체

JS에서 함수는 객체다. 정확히 말하면 일급 객체.

  1. 무명의 리터럴로 생성가능(런타임 생성)
  2. 변수나 자료구조에 저장 가능
  3. 함수의 매개변수 전달 가능
  4. 함수의 반환값으로 사용가능

4가지 조건을 만족하면 일급 객체라고한다.
고로 함수객체다.
객체이다.
=> 할당, 객체 프로퍼티 할당, 배열 요소 등 가능

함수의 프로퍼티

객체는 프로퍼티를 갖는다.
함수도 프로퍼티를 가져야 마땅하다.


인수, (caller는 비표준이다), 매개변수의 개수, 함수 이름, 프로토타입

argument프로퍼티는 재밌는 기능이 있다.


Symbol.iterator라는 프로퍼티로 arguments를 순회가능하게 만든다.
이는 나중에 자세히 살펴볼것이다.

arguments객체는 매개변수의 개수를 확정할 수 없는 가변인자함수를 구현할때 유용하다.

function sum(){
	let res = 0;
  	for(let i = 0; i<arguments.length; i++){
    	res += arguments[i];
    }
  return res;
}
console.log(sum(1,2,3)) //...6

참고로 arguments객체는 유사배열객체여서 배열순회 메소드를 사용하려면 call,apply,bind등을 사용해야 한다.
es6이후에는 rest파라미터를 사용하면 간단하다.

function sum(){
	const arr = Array.prototype.slice.call(arguments);
  return arr.reduce...
}
console.log(sum(1,2,3)) //...6
  
//vs
  
function sum (...args){
	return args.reduce...
}

프로토타입프로퍼티는 생성자 함수로 호출할수 있는 함수 객체만 소유하고있다.


출처는 이웅모 저자님의 '모던 javascript deep dive'입니다

profile
모르는 것을 모른다고 하기

0개의 댓글