실행 컨텍스트는 실행할 코드에 제공할 환경정보를 담아놓은 객체라고 했다.
그 안에는 VE와 LE 그리고 this bindings가 있다.
this는 쉽게 말해서 함수를 호출할 때 결정된다.
전역 공간에서 this를 호출하면 브라우저 환경에서는 window 객체를 가리키고, node 환경에서는 global 객체를 가리킨다.
먼저 함수와 메서드를 혼용하지 말자.
그 기준은 독립성으로, 함수는 호출의 주체가 없어도 독립적인 기능이 가능하지만 메서드는 호출의 주체가 필요하다.
따라서 함수의 this는 전역 객체를 가리키고
메서드의 this는 호출의 주체를 가리킨다.
// 함수의 this
var func = function (x) {
console.log(this, x); };
func(1); // Window { ... }
// 메서드의 this
var obj = {
method: function (x) { console.log(this, x) }
};
obj.method(1); // { method: f }
위와 같이 브라우저 환경에서 함수의 this는 전역객체인 window를 바인딩하고, 메서드의 경우 자신을 호출한 주체인 객체(obj)를 바인딩한다.
화살표 함수는 실행 컨텍스트를 생성할 때 this 바인딩 과정 자체가 없다.
따라서 this는 이전의 값이 유지된다.
var obj = {
outer: function() {
console.log(this); // (1) obj
var innerFunc = () => {
console.log(this); // (2) obj
};
innerFunc();
}
}
obj.outer();
위와 같은 코드에서 확인할 수 있듯이, 화살표 함수 속에서 this를 출력해보면 outer 함수에서 바인딩 됐던 this의 값이 유지된다.
따라서 함수와 화살표 함수의 가장 큰 차이점이 무엇이냐고 묻는다면 this 바인딩이라고 답하면 됨
생성자는 인스턴스를 만들기 위한 틀로, 붕어빵(인스턴스)을 만드는 붕어빵 틀(생성자) 같은거다.
var Cat = function (name, age) { this.bark = ' ';
this.name = name;
this.age = age;
};
var choco = new Cat('초코', 7) // this : choco ;
var nabi = new Cat('나비', 5); // this : nabi
위와 같이 생성자 함수에서의 this는 생성자(틀)로 만들어진 인스턴스(구체적인 내용물)를 가리킨다. 여기서는 choco와 nabi이다.
this를 명시적으로 바인딩해주는 메서드가 몇 가지 있다.
var func = function (a, b, c) {
console.log(this, a, b, c)
}
func.call({x : 1}, 1, 2, 3}); // {x : 1} 1 2 3
call을 사용하지 않으면 위 함수에서 this는 전역 객체인데, call 메서드를 사용해서 this를 명시적으로 {x : 1}이라는 객체로 바인딩 해준 것이다.
함수 뿐만 아니라 호출 주체가 있는 객체의 메서드일 때도 마찬가지로 call을 통해 설정한 객체로 바인딩 해줄 수 있다.
call은 함수를 즉시 실행한다.
var obj = {
a: 1,
method : function (x, y) {
console.log(this.a, x, y);
}
};
obj.method.call({a : 4}, [5, 6]); // 4 5 6
이런식으로 call과 똑같이 함수 즉시 실행, 명시적으로 객체 바인딩 할 수 있음 매개변수 넘겨주는것만 [] 담아서 보내면 됨 ㅇㅇ
그런데 이 apply, call의 개꿀 기능은 바로...
객체에 배열 메서드 적용할 수 있게 해줌
사실 입니다.
예를 들어 객체에는 push라는 배열 메서드 못 쓰잖슴? 그렇지만 call,apply 사용하면 유사배열객체(length가 존재하는 거)에 차용할 수 있음
var obj = {
0 : '일',
1 : '이',
2 : '삼',
length : 3
}
Array.prototype.push.call(obj, 'd');
console.log(obj); // {0: '일', 1: '이', 2: '삼', 3: 'd', length: 4}
핵심은 저기서 length 빠지면 제 기능 안 함 ㅇㅇ
무조건 객체 -> length 프로퍼티 부여해서 유사배열 객체로 인식해줘야
Array.prototype.push.call(객체, 매개변수, ..)
사용 가능해짐
근데 걍 Array.from(obj)해서 사용해도 될듯. . ^^. .