- 자바스크립트 객체의 프로퍼티나 메소드에 접근하는 원리
- 스코프 - 규칙, 모듈, 클로저, 호이스팅
자바스크립트는 프로토타입 기반으로 객체 지향의 상속 개념 구현한다.
모든 객체는 자신의 부모 역할을 하는 프로토타입 객체 (이하 프로토타입)의 참조 링크를 가지며, 이 링크를 통해 프로토타입으로부터 프로퍼티나 메서드를 상속받는다. 프로토타입 또한 또 다른 상위 프로토타입으로부터 상속받기 가능하다.

객체의 프로토타입은 참조링크 형태로 [[Prototype]] 내부 프로퍼티에 저장된다. 참조링크 형태로 저장 = 동일 프로토타입 상속 시 모두 같은 프로퍼티와 메서드 공유
[[Prototype]]은 자바스크립트 엔진 내부에서만 사용하는 숨겨진 프로퍼티이지만, 브라우저에서 __proto__ 프로퍼티로 접근 가능
하지만 __proto__는 공식적인 접근 방식 아니니까 웬만하면 쓰지 마로라
[[Prototype]] 접근하려면 Object.getPrototypeOf() 하도록..
const obj = {
name: 'obj1'
}
console.log(obj.toString()); // [Object object]
obj 객체에 메서드가 없는데 호출 가능한 이유?
최상위 프로토타입은
Object.prototype이다.
모든 함수는 prototype 이라는 특별한 프로퍼티가 존재한다. 이 프로퍼티는 참조링크 [[Prototype]] 과 다르다!! 함수의 prototype 프로퍼티는 특수 역할을 수행하기는 하지만, 일반적인 객체의 프로퍼티이며, 프로토타입을 가리키는 참조링크가 아니다.
prototype 프로퍼티의 역할생성자 함수로 생성된 객체는 생성자함수의 prototype프로퍼티가 프로토타입( [[Prototype]] )으로 설정된다.
function Vehicle(type) {
this.type = type;
}
const vehicle = new Vehicle('Car');
console.log(Vehicle.prototype === vehicle.__proto__); //true!

함수의 prototype 프로퍼티는 constructor 프로퍼티 하나만 가진 객체.
constructor 프로퍼티는 자신과 연결된 생성자 함수를 가리키며, 이를 통해 객체가 어떤 생성자함수를 통해 생성되었는지 알 수 있다. 즉, 상호 참조 관계
스코프는 변수나 매개변수가 접근할 수 있는 범위를 결정한다. 자바 스크립트의 스코프는 아래와 같다
varlet, const프로그래밍 언어의 스코프는 대부분 동적 스코프와 렉시컬 스코프 두 가지 방식으로 동작한다. 동적 스코프는 런타임 중 함수의 호출에 의해 결정되고, 렉시컬 스코프는 변수나 함수를 어디에 작성하였는지를 기초하여 결정된다. 자바스크립트는 렉시컬 스코프 기반 언어이다.
❓ 자바스크립트는 렉시컬 스코프를 따르고, this 바인딩만 함수 호출방법에 따라 동적으로 변하는 것
function foo(){
var a = 1;
function bar(b) {
console.log(a,b)
}
bar(2);
}
foo();
위 코드의 진행 순서는 아래와 같다.
이러한 스코프들의 연결관계를 스코프 체인이라고 하고, 스코프체인을 따라 검색하는 과정을 스코프 체이닝이라고 한다.
선언문이 스코프 내의 가장 최상단으로 끌어올려지는 것
호이스팅은 스코프별로 동작한다.
: 함수의 렉시컬 스코프를 기억하여 함수가 렉시컬 스코프를 벗어날 외부 스코프에서 실행될 때에도 자신의 렉시컬 스코프에 접근할 수 있게 해주는 것
함수를 사용하는 곳이면 어디든지 적용 가능하다. 클로저를 활용하면 특정 상태를 기억하여 캡슐화하거나 하나의 모듈을 정의하는 패턴으로 확장 가능하다.
function foo(){
var a = 1;
function bar() {
console.log(a) // 1
}
bar();
}
foo();
bar()와 같은 내부 함수가 자신을 감싼 외부 함수를 벗어나 완전히 독립적인 스코프에서 실행되는 경우를 클로저라고 한다.
위 코드를 클로저를 이용한 코드로 변경하면 아래와 같은 코드가 된다.
function foo(){
var a = 1;
function bar() {
console.log(a) // 1
}
return bar();
}
const baz = foo()
baz() // 1
위 코드의 진행 순서
bar() 는 렉시컬 스코프체인으로 foo() 함수의 스코프를 기억baz 사용하여 bar()호출bar()는 자신의 스코프에서 변수 a를 찾는다foo()의 스코프에서 a 찾기foo()의 스코프에서 a 찾아서 1 출력클로저를 사용하여 외부에서도 원래의 렉시컬 스코프에 접근가능하다