- 내부 슬롯과 내부 메서드란 무엇인가?
: 프로퍼티 어트리뷰트를 이해하기 위한 선행적 개념
: 자바스크립트 엔진의 구현 알고리즘을 설명하기 위한 가상의 프로퍼티와 가상의 메서드
: ECMAScript 사양에 등장하는[[ ]]
로 감싼 이름들이 내부 슬롯과 내부 메서드에 해당함
- 내부 슬롯과 내부 메서드에 어떻게 접근할 수 있는가?
: 자바스크립트 엔진 내부에서 실제 동작하지만, 외부로 공개된 객체의 프로퍼티가 아니므로 원칙적으로 접근 불가능
: 그러나 일부 내부 슬롯, 내부 메서드는 간접적으로 접근할 수 있는 수단 제공
ex) 모든 객체가 가지는 내부 슬롯[[Prototype]]
은 접근자 프로퍼티인__proto__
를 통해 접근 가능
- 프로퍼티 어트리뷰트란 무엇인가?
: 자바스크립트 엔진이 프로퍼티를 생성할 때 기본 값으로 정의하는 프로퍼티의 상태를 의미함
: 쉽게 말하면 자바스크립트 엔진이 관리하는 내부 슬롯, 즉 가상의 프로퍼티
- 프로퍼티 디스크립터 객체란 무엇인가?
: 내부 슬롯인 프로퍼티 어트리뷰트를 간접적으로 확인할 수 있는 객체
:Object.getOwnPropertyDescriptor
를 사용하여 접근 가능
- 프로퍼티의 종류에는 무엇이 있고, 각각 어떤 특징이 있는가?
: 데이터 프로퍼티와 접근자 프로퍼티
: 데이터 프로퍼티는 키와 값으로 구성된 일반적인 프로퍼티를 의미함
: 접근자 프로퍼티는 자체적으로 값을 가지지 않고 데이터 프로퍼티의 값을 읽거나 저장할 때 호출되는 접근자 함수로 구성된 프로퍼티를 의미함, 여기서의 접근자 함수를 getter, setter 함수라고도 하고, 둘 중 하나만 정의해도 상관없음
- 데이터 프로퍼티의 프로퍼티 어트리뷰트에는 무엇이 있는가?
:
[[Value]]
(프로퍼티의 값)
:[[Writable]]
(값의 갱신 가능 여부)
:[[Enumerable]]
(열거 가능 여부)
:[[Configurable]]
(재정의 가능 여부)
[[Value]]
는 무엇이고, 어떤 특징이 있는가?: 프로퍼티 키를 통해 프로퍼티 값에 접근하면 반환되는 값
: 프로퍼티 값이 변경되면[[Value]]
에 값이 재할당됨
: 프로퍼티가 없는 경우 동적으로 생성한 프로퍼티의[[Value]]
에 값 저장
[[Writable]]
은 무엇이고, 어떤 특징이 있는가?: 프로퍼티 값의 변경 가능 여부로, 불리언 값을 가짐
: 값이false
인 경우[[Value]]
의 값을 변경할 수 없는 읽기 전용 프로퍼티가 됨
[[Enumerable]]
은 무엇이고, 어떤 특징이 있는가?: 프로퍼티의 열거 가능 여부로, 불리언 값을 가짐
: 값이false
인 경우 프로퍼티를for in
문이나Object.keys
로 열거할 수 없음
[[Configurable]]
은 무엇이고, 어떤 특징이 있는가?: 프로퍼티의 재정의 가능 여부로, 불리언 값을 가짐
: 값이false
인 경우 프로퍼티의 삭제와 프로퍼티 어트리뷰트 값의 변경이 금지됨
- 접근자 프로퍼티의 프로퍼티 어트리뷰트에는 무엇이 있는가?
:
[[Get]]
(접근자 함수)
:[[Set]]
(접근자 함수)
:[[Enumerable]]
(열거 가능 여부)
:[[Configurable]]
(재정의 가능 여부)
[[Get]]
은 무엇이고, 어떤 특징이 있는가?: 데이터 프로퍼티의 값을 읽을 때 호출되는 접근자 함수를 의미함
: 접근자 프로퍼티 키로 프로퍼티 값에 접근하면 getter 함수가 호출되고, 함수의 결과가 프로퍼티 값으로 반환됨
[[Set]]
은 무엇이고, 어떤 특징이 있는가?: 데이터 프로퍼티의 값을 저장할 때 호출되는 접근자 함수
: 접근자 프로퍼티 키로 프로퍼티 값을 저장하면 setter 함수가 호출되고, 함수의 결과가 프로퍼티 값으로 저장됨
[[Get]]
과 같은 내부 메서드가 호출되면 어떻게 동작하는가?(1) 먼저 프로퍼티 키가 유효한지, 즉 문자열 또는 심벌인지 확인
(2) 프로토타입 체인에서 프로퍼티를 검색
(3) 검색한 프로퍼티가 데이터 프로퍼티인지 접근자 프로퍼티인지 확인
(4) 프로퍼티 종류에 따라 적절한 결과를 반환함
- 프로토타입 체인이란?
: 프로토타입이란 어떤 객체의 상위 객체 역할을 하는 객체, 하위 객체에게 자신의 프로퍼티와 메서드를 상속하여 자유롭게 사용 가능하게 함
: 이러한 프로토타입이 단방향 연결 리스트 형태로 연결되어 있는 구조가 프로토타입 체인
- 데이터 프로퍼티와 접근자 프로퍼티는 어떻게 구별할 수 있는가?
: 프로퍼티 디스크립터 객체의 프로퍼티가 서로 다름
: 이는Object.getOwnPropertyDescriptor
로 확인 가능
- 프로퍼티 정의란 무엇인가?
: 새로운 프로퍼티를 추가하면서 프로퍼티 어트리뷰트를 명시적으로 정의하거나, 기존 프로퍼티의 프로퍼티 어트리뷰트를 재정의하는 것을 의미함
: 프로퍼티 정의를 통해 객체의 프로퍼티가 어떻게 동작해야 하는지 정의할 수 있음
- 프로퍼티를 어떻게 정의할 수 있는가?
:
Object.defineProperty
메서드 사용, 매개변수로 객체의 참조와 데이터 프로퍼티 키, 프로퍼티 디스크립터 객체 전달
: 디스크립터 객체의 프로퍼티를 생략하면[[Value]]
,[[Get]]
,[[Set]]
값의 경우undefined
, 나머지 어트리뷰트 값은false
로 자동 정의됨
:Object.defineProperties
메서드 사용하면 여러 개의 프로퍼티를 한 번에 정의할 수 있음
- 객체의 변경을 방지하는 이유는 무엇인가?
: 외부 상태를 참조 및 변경하지 않는 순수 함수의 사용을 통해 함수형 프로그래밍을 지향하려는 목적
- 객체의 변경은 어떻게 방지할 수 있는가?
: 확장을 금지하는
Object.preventExtensions
메서드 사용
: 밀봉하는Object.seal
메서드 사용
: 동결하는Object.freeze
메서드 사용
- 객체의 확장을 어떻게 금지할 수 있는가?
:
Object.preventExtensions
메서드 사용
: 확장 금지란 프로퍼티 추가 금지를 의미함, 삭제나 값 변경 등 나머지는 다 허용
: 여기서의 프로퍼티 추가는 동적 추가,Object.defineProperty
두 가지 방법 모두 해당함
:Object.isExtensible
메서드로 확장 가능 여부 확인 가능
- 객체를 어떻게 밀봉할 수 있는가?
:
Object.seal
메서드 사용
: 프로퍼티 추가 및 삭제 금지, 프로퍼티 재정의 금지
: 즉 밀봉된 객체는 읽기(참조)와 쓰기(값 갱신)만 가능
:Object.isSealed
메서드로 밀봉 여부 확인 가능
- 객체를 어떻게 동결할 수 있는가?
:
Object.freeze
메서드 사용
: 프로퍼티 추가 및 삭제, 프로퍼티 어트리뷰트 재정의, 프로퍼티 값 갱신 금지
: 즉 동결된 객체는 읽기(참조)만 가능
:Object.isFrozen
메서드로 동결 여부 확인 가능
- 불변 객체란 무엇인가?
: 객체 확장 금지, 밀봉, 동결과 같은 메서드는 얕은 변경 방지에 해당하기 때문에 중첩된 객체까지는 영향을 줄 수 없음
: 불변 객체란 중첩된 객체까지 변경이 방지된 객체를 의미
- 객체를 어떻게 불변하게 만들 수 있는가?
: 객체를 값으로 가지는 중첩된 프로퍼티에 대해 재귀적으로
Object.freeze
메서드를 호출해야 함
- 생성자 함수란 무엇인가?
:
new
연산자와 함께 호출하여 객체를 생성하는 함수
: 생성자 함수에 의해 생성된 객체를 인스턴스라고 함
:String
,Number
,Boolean
,Function
,Array
,Date
,RegExp
,Promise
등 다양한 빌트인 생성자 함수 제공됨
Object
생성자 함수란 무엇인가?:
new
연산자와 함께Object
생성자 함수를 호출하여 빈 객체를 생성 및 반환하는 방법을 의미함
ex)new Object();
: 빈 객체 생성 이후 프로퍼티, 메서드를 추가하여 객체 완성 가능
- 생성자 함수 사용 시 주의할 점은 무엇인가?
:
new
연산자와 함께 사용하지 않으면 일반 함수로 동작함
- 생성자 함수는 왜 사용하는가?
: 객체 리터럴에 의한 객체 생성 방식은 단 하나의 객체만 생성하기 때문에 동일한 프로퍼티 구조를 갖는 객체를 여러 개 생성해야 한다면 비효율적임
: 프로퍼티 값은 다를 수 있어도 메서드는 동일한 경우가 많은데, 객체 리터럴을 사용하는 경우 매번 동일한 메서드를 기술해야 하는 번거로움을 해결하기 위해 생성자 함수 사용
- 생성자 함수에 의한 객체 생성 방식의 장점은 무엇인가?
: 객체(인스턴스)를 생성하기 위한 템플릿(클래스)처럼 사용하여 프로퍼티 구조가 동일한 객체 여러 개를 간편하게 생성 가능
: 이때 생성자 함수 내부에this
키워드 사용하는데, 여기서의this
는 생성자 함수가 생성할 인스턴스를 가리킴
- 생성자 함수는 인스턴스를 어떻게 생성하는가?
(1) 인스턴스 생성과
this
바인딩
: 생성자 함수가 호출되면 함수 몸체의 코드를 실행하는 런타임 이전에 암묵적으로 빈 객체(인스턴스)를 생성하고, 생성된 인스턴스가this
에 바인딩되어this
는 생성할 인스턴스를 가리키게 됨(2) 인스턴스 초기화
: 그 후 생성자 함수 몸체의 코드가 한 줄씩 실행되어 생성한 인스턴스를 초기화하는 과정을 거침
: 구체적으로 인스턴스에 프로퍼티와 메서드를 추가하는데, 이때 생성자 함수가 인수로 전달 받은 초기값을 할당하여 초기화하거나 고정 값을 할당함(3) 인스턴스 반환
: 생성자 함수 내부의 처리가 끝나고 완성된 인스턴스가 바인딩된this
가 암묵적으로 반환됨
: 이때this
가 아닌 다른 객체를 반환하면this
가 아니라 다른 객체가 반환되기 때문에return
문을 생략해야 함
- 일반 함수로 호출하는 것과 생성자 함수로 호출하는 것은 어떤 차이가 있는가?
: 함수 선언문과 함수 표현식으로 정의한 함수를 호출하는 것은 동일하고, 다만
new
연산자의 차이가 있음
: 내부적으로는 호출되는 내부 메서드가[[Call]]
인지,[[Construct]]
인지 차이가 있음
[[Call]]
이란 무엇인가?: 함수가 일반 함수로 호출되었을 때 호출되는 내부 메서드, 이 메서드를 갖는 함수 객체를 callable이라고 함
: 모든 함수 객체는 호출할 수 있기 때문에 무조건[[Call]]
을 가지고 있음
[[Construct]]
란 무엇인가?: 함수가 생성자 함수로 호출되었을 때 호출되는 내부 메서드, 이 메서드를 갖는 함수 객체를 constructor라고 함
: 만약 함수 객체가[[Construct]]
를 갖지 않는다면 non-constructor라고 함
: 즉 constructor는 생성자 함수로서 호출할 수 있는 함수, non-constructor는 생성자 함수로서 호출할 수 없는 함수
- constructor와 non-constructor는 어떻게 구분할 수 있는가?
: 자바스크립트 엔진이 함수 정의 방식을 평가함, 즉 함수 객체를 생성할 때의 정의 방식에 따라 자체적으로 구분함
: constructor는 정의 방식이 함수 선언문, 함수 표현식, 프로퍼티 값으로 할당된 함수, 클래스인 함수 객체
: non-constructor는 정의 방식이 메서드 축약 표현, 화살표 함수인 함수 객체
: non-constructor인 함수 객체는 내부 메서드[[Construct]]
를 가지지 않기 때문에new
연산자와 함께 호출하면 에러 발생
- 메서드 축약 표현이란 무엇인가?
: ES6에 추가된 메서드 정의 방식
: 프로퍼티 키에 따로 값을 할당하지 않고 프로퍼티 키를 함수 이름처럼 사용
ex)x() {}
new
연산자는 왜 중요한가?: 일반 함수와 생성자 함수의 호출 방식을 결정하는 표현 방식의 유일한 차이점이기 때문
: 또한new
연산자의 유무에 따라this
가 전역 객체를 가리킬지, 생성될 인스턴스를 가리킬지 결정됨
- 보편적으로 일반 함수와 생성자 함수는 어떻게 구분하는가?
:
new
연산자 말고는 일반 함수와 생성자 함수의 형식 차이가 없기 때문에 보편적으로 생성자 함수는 파스칼 케이스로 명명
new.target
이란 무엇인가?:
this
와 유사하게 constructor인 함수 내부에서 암묵적 지역 변수처럼 사용할 수 있는 프로퍼티, 메타 프로퍼티라고 부름
: IE에서는new.target
을 지원하지 않기 때문에 주의해야 함
: 함수 내부에서new.target
사용하면 생성자 함수로서 호출되었는지 여부를 확인 가능
: 생성자 함수로서 호출되었다면new.target
은 함수 자신을 가리키고, 일반 함수로서 호출되었다면new.target
의 값은undefined
를 반환함
:new.target
을 조건식으로 활용하여 일반 함수로 호출해도 생성자 함수로 호출한 것처럼 사용, 실수 방지 가능
- IE처럼
new.target
을 사용할 수 없는 경우에는 어떻게 해야 하는가?:
instanceof
연산자를 사용하여this
가 함수가 생성할 인스턴스를 가리키는지 여부를 조건식에 사용, 가리키지 않는다면 재귀적으로new
연산자를 붙여 다시 호출할 수 있음
Object
,Function
생성자 함수를new
연산자 없이 호출하면 어떻게 되는가?:
new
연산자 없이 호출해도new
연산자와 함께 호출했을 때와 동일하게 객체, 함수 반환
String
,Number
,Boolean
생성자 함수를new
연산자 없이 호출하면 어떻게 되는가?:
new
연산자와 함께 호출하면String
,Number
,Boolean
객체 생성하여 반환
:new
연산자 없이 호출하면 각각의 원시 값을 반환하는데, 이를 이용하여 명시적으로 데이터 타입을 변환하기도 함
- 일급 객체란 무엇인가?
: 무명의 리터럴로 생성할 수 있어야 함, 즉 런타임에 생성 가능한 객체여야 함
: 변수나 자료구조(객체, 배열)에 저장할 수 있어야 함
: 함수의 매개변수에 전달할 수 있어야 함
: 함수의 반환값으로 사용할 수 있어야 함
- 함수는 일급 객체인가?
: 자바스크립트의 함수는 일급 객체의 조건을 만족하므로 일급 객체
: 즉 함수는 객체와 동일하게 사용할 수 있고, 객체는 값이기 때문에 값을 사용할 수 있는 변수 할당문, 객체의 프로퍼티 값, 배열의 요소, 함수 호출의 인수, 함수 반환문에 전부 함수 리터럴로 정의 가능
- 일급 객체로서 함수가 갖는 의의는 무엇인가?
: 함수의 매개변수, 반환값으로 사용할 수 있기 때문에 함수형 프로그래밍이 가능함
- 함수 객체와 일반 객체의 차이는 무엇인가?
: 호출 여부의 차이, 함수는 호출할 수 있음
: 프로퍼티의 차이, 함수 객체는 일반 객체에 없는 고유의 프로퍼티를 가짐
- 함수 객체가 가지는 고유의 프로퍼티에는 무엇이 있는가?
:
console.dir
로 확인해보면 일반 객체에는 없는 함수 객체 고유의 데이터 프로퍼티로arguments
,caller
,length
,name
,prototype
를 가짐
:__proto__
는Object.prototype
객체를 상속받아 사용하는 것이지, 함수 객체 자체의 프로퍼티는 아님
arguments
프로퍼티란 무엇인가?: 값으로
arguments
객체를 가지는 프로퍼티, 즉 함수 호출 시 전달된 인수들의 정보를 담고 있는 유사 배열 객체를 의미함
:arguments
객체는 함수 내부에서 지역 변수처럼 사용할 수 있지만, 함수 외부에서 참조할 수 없음
:arguments
프로퍼티는 표준에서 폐지되었기 때문에Function.arguments
처럼 사용하기 보다,arguments
객체를 직접 참조하는 것이 바람직함
: 함수 정의 시 선언한 매개변수보다 인수가 적게 전달되는 경우undefined
로 초기화된 그 상태 유지, 매개변수보다 인수가 더 많다면 초과된 인수는 무시되지만arguments
객체에 정보가 저장되기 때문에 사용할 수 있음
arguments
객체의 구성 요소로는 무엇이 있는가?: 인수의 순서가 프로퍼티의 키로 저장되고, 전달 받은 인수의 값이 프로퍼티의 값으로 저장됨
: 기본으로 포함된callee
프로퍼티는 호출되어arguments
객체를 생성한 함수 자신의 정보를 가짐
: 기본으로 포함된length
프로퍼티는 전달 받은 인수의 개수를 값으로 가짐
: 기본으로 포함된Symbol(Symbol.iterator)
프로퍼티는arguments
객체를 순회 가능한 이터러블로 만들기 위한 프로퍼티
arguments
객체는 어떤 경우 사용할 수 있는가?: 매개변수 개수를 확정할 수 없는 가변 인자 함수를 구현할 때 유용하게 사용할 수 있음
- 유사 배열 객체란 무엇인가?
:
length
프로퍼티를 가지고 있기 때문에for
문으로 순회가 가능한 객체
arguments
객체는 유사 배열 객체인가?: 배열 형태로 인수의 정보를 담고 있지만, 사실 배열이 아닌 유사 배열 객체임
: 배열이 아니기 때문에arguments
객체에 배열 메서드를 사용하면 에러가 발생함
: 배열 메서드를 사용하려면Function.prototype.call
,Function.prototype.apply
를 사용하여 간접 호출해야 하는 번거로움
: 번거로움을 해결하기 위해 ES6 이후에 도입된 Rest 파라미터(…
)를 매개변수 자체에 사용하여arguments
객체는 많이 사용하지 않게 됨
caller
프로퍼티란 무엇인가?: ECMAScript 표준 사양에 포함되지 않은 비표준 프로퍼티
: 함수 자신을 호출한 함수를 가리킴, 브라우저 환경에서 호출한 함수가 없는 경우 프로퍼티 값으로null
을 가짐
length
프로퍼티란 무엇인가?: 함수를 정의할 때 선언한 매개변수의 개수를 프로퍼티 값으로 가짐
arguments
객체의length
프로퍼티와 함수 객체의length
프로퍼티는 어떻게 다른가?:
arguments
객체의length
프로퍼티는 호출 시 전달 받은 인수의 개수를 프로퍼티 값으로 가짐
: 함수 객체의length
프로퍼티는 정의 시 기술한 매개변수의 개수를 프로퍼티 값으로 가짐
name
프로퍼티란 무엇인가?: 함수 이름을 프로퍼티 값으로 가지는 프로퍼티
: ES6 이후부터 표준 프로퍼티가 되었기 때문에 ES5에서 익명 함수 표현식은name
프로퍼티 값을''
로 가지지만, ES6에서는 함수 객체를 가리키는 식별자를 값으로 가짐
__proto__
접근자 프로퍼티란 무엇인가?:
[[Prototype]]
내부 슬롯이 가리키는 프로토타입 객체에 간접적으로 접근하기 위해 사용하는 접근자 프로퍼티
- 프로토타입 객체란 무엇인가?
: 자바스크립트의 모든 객체가 가지고 있으며 객체지향 프로그래밍의 상속을 구현하기 위한 것
prototype
프로퍼티란 무엇인가?: 생성자 함수로 호출할 수 있는 함수 객체, 즉 constructor만 소유하는 프로퍼티
: 생성자 함수가 생성할 인스턴스의 프로토타입 객체를 가리킴