두개의 개념을 먼저 살펴본다.
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에서 함수는 객체다. 정확히 말하면 일급 객체.
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'입니다