어휘적 환경( Lexical Environment )
→ 선언 여부에 따라 Lexical 환경에 저장된 내용 달라짐 … 함수나 코드 블록마다 각각의 Lexical 환경이 생성됨
전역 Lexical 환경
: 스크립트 → 최상위 외부 렉시컬 환경내부 Lexical 환경
: 전역 Lexical 환경을 참조, 지역 변수나 매개변수 저장사용하려는 변수 등이 내부 Lexical 환경에 없으면 외부 Lexical 환경으로 점차 이동 …
클로저( Closure )
→ 함수와 렉시컬 환경의 조합
함수가 생성될 당시의 외부 변수를 기억 → 생성 이후에도 내부 함수에서 계속 접근 가능
function makeAdder(x) {
return function(y) {
return x + y;
}
}
const add3 = makeAdder(3);
// add3 함수가 생성된 이후에도 상위 함수인 makeAdder의 x에 접근 가능해짐
console.log(add3(2)); // makeAdder(3) -> function(2) { return 3 + 2 } ... 5
// add10과 add3은 서로 다른 렉시컬 환경을 가짐
const add10 = makeAdder(10);
console.log(add10(5)); // 15
console.log(add3(1)) // 4
모든 함수에서 사용할 수 있음, 객체를 인자로 받아 this를 특정 값으로 지정할 수 있음
const mike = {
name : "Mike",
};
const tom = {
name : "Tom",
};
function showThisName() {
console.log(this.name);
}
showThisName();
showThisName.call(mike); // 객체의 method인 것처럼 사용 가능
showThisName.call(tom);
// 매개변수 사용
function update(birthYear, occupation) {
this.birthYear = birthYear;
this.occupation = occupation;
}
함수 매개변수를 처리하는 방법을 제외하면 call과 동일함 ( 배열로 받음 )
update.apply(tom, [2002, "teacher"]);
console.log(tom);
함수의 this 값을 영구히 변경
const updateMike = update.bind(mike);
updateMike(1980, 'police');
console.log(mike);
__proto__
prototype 객체 … 만약 hasOwnProperty를 재정의할 경우 재정의된 내용이 나옴
const user = {
name : "Mike"
}
console.log(user.hasOwnProperty('name')); // true
const car = {
wheels : 4,
drive() {
console.log("drive...");
},
};
const bmw = {
color : "red",
navigation : 1,
}
const benz = {
color : "black",
}
__proto__
재정의를 통해 car를 bmw, benz의 Prototype으로 사용 = car를 상속 받음
bmw.__proto__ = car; // 출력 시에나 hasOwnProperty, Object.keys()에는 나오지 않음
benz.__proto__ = car;
// 상속은 계속 이어질 수 있음
const x5 = {
color : "white",
name : "x5",
};
x5.__proto__ = bmw;
console.log(x5.color); // 원래의 property를 우선적으로 ! -> prototype chain
console.log(x5.navigation);
// 생성자 함수를 이용
const BMW = function (color) {
this.color = color;
}
BMW.prototype.wheels = car.wheels;
BMW.prototype.drive = car.drive;
const x5 = new BMW("pink");