record : 식별자정보를 컨택스트에 기록.
수집대상정보는 함수안의 매개변수 식별자, 함수자체, var로 선언된 변수 식별자.
수집이된다 => 호이스팅이 된다.
수집방법 => 컨텍스트 내부를 처음부터 끝까지 순서대로 수집
수집만 할뿐 실행을 하는게 아님!
호이스팅 = 식별자 정보를 밑에서 맨위로 끌어 올림 = 레코드를 수집하는 과정
호이스팅 규칙
1.매개변수나 변수는 선언부를 호이스팅
function a (x) {
console.log(x);
var x;
console.log(x);
var x = 2;
console.log(x);
}
a(1); //호이스팅 적용전
function a () {
var x; //매개변수 1로 처음 들어온 x
var x; //두번째 그냥 선언만 한 x
var x; //세번째 2 선언한 x
x = 1; //선언부를 제외하고 남은 1
console.log(x); //1
console.log(x); //1
x = 2; //선언부를 제외하고 남은 2
console.log(x); //2
}
a(1); //호이스팅 적용후
function a () {
console.log(b);
var b = 'bbb';
console.log(b);
function b() { }
console.log(b);
}
a(); //호이스팅전
function a () {
var b;
function b() { };
console.log(b); //함수func
b = 'bbb';
console.log(b); //bbb
console.log(b); //bbb
}
a(); //호이스팅 후
함수선언문 => 함수명이 곧 변수명
함수표현식 => 정의한 함수를 별도 변수에 할당
console.log(sum(1, 2));
console.log(multiply(3, 4));
function sum (a, b) { // 함수 선언문 sum
return a + b;
}
var multiply = function (a, b) { // 함수 표현식 multiply
return a + b;
}// 호이스팅 전
function sum (a, b) { // 함수 선언문은 전체를 hoisting
return a + b;
}
var multiply; // 변수는 선언부만 hoisting
console.log(sum(1, 2));
console.log(multiply(3, 4));
multiply = function (a, b) { // 변수의 할당부는 원래 자리
return a + b;
};//호이스팅 후
협업을 많이 하고 복잡해질수록 함수표현식을 활용하는 게 좋음.
예상치 못한 오류,동작을 방지차원
스코프 : 식별자에 대한 유효범위 , 변수가 어디까지 접근 가능한지를 정의
스코프체인 : 현재 실행컨텍스트 에서 해당 식별자를 찾은뒤 없으면 가까운 외부스코프로 이동하며 마지막으로 전역 스코프까지 검색하는 과정
-outer : 현재 호출된함수가 선언될당시 외부환경정보를 가지고있음
해당 함수가 어디에 선언되었는지,
그리고 어떤 스코프 체인을 따라야 하는지를 결정하는 데 사용.
함수가 선언될 때의 스코프에 대한 참조를 저장
var a = 1;
var outer = function() {
var inner = function() {
console.log(a); // var a;만 호이스팅으로 끌어올려져서 undefined
var a = 3; //console.log(a); 찍힌후 a=3할당되지만
//inner안에서의 변수선언은 inner안에서만 적용 이라 빠져나가지못함.
};
inner();
console.log(a); //outer안에 a라는 요소없음
//바깥에 전역함수로 나가서 var a = 1; 발견
};
outer();
console.log(a); // 1
this : 실행 컨텍스트에 따라 현재 객체를 가리키는 참조
this의 값은 함수가 호출되는 방식에 따라 달라짐.
this는 실행 컨텍스트가 생성될 때 결정. => this 를 bind한다.
전역객체를 가리킴.
런타임 환경에 따라 this는 window(브라우저 환경) 또는 global(node 환경).
메서드를 호출한 객체를 가리킴
함수 vs 메서드
독립적으로 실행이 된다 => 함수
종속적으로 호출한 대상에 대한 동작을 실행한다 => 메서드
this 할당
var func = function (x) {
console.log(this, x);
};
func(1); // Window { ... } 1 .호출할 요소가 없음 .
//그래서 여기서의 this는전역객체를 가리킴
var obj = {
method: func,
};
obj.method(2); // { method: f } 2 obj객체안에 method프로퍼티에 2를 인자로줌
//method는 키값으로 func함수를 할당받았고 obj안의 func의 this는
//호출한 객체인 obj를 가리킴
//여기서 { method: f }는 obj 객체가 method라는 프로퍼티를 가지고 있으며,
//그 값이 함수임을 나타냄(f는 함수를 표시하는 일반적인 방법)
함수내부에서의 this<>
함수를 함수로서 호출할경우 this는 지정되지 않음.
독립적으로 호출시 항상 전역객체를 가리킴.
메서드의 내부함수에서의 this
예외없이 this는 전역객체를 가리킴.
this바인딩 관해서는 함수를 실행하는 환경은 중요하지 않고 ,
해당함수를 호출하는 구문 앞에 (.)점 또는 ([])대괄호 표기가 있는지 체크
있으면 호출한 요소를 가리키고 없으면 전역객체를 가리킴
var obj1 = {
outer: function() {
console.log(this); // (1) this가 obj1가리킴
// AS-IS
var innerFunc1 = function() {
console.log(this); // (2) 독립적 실행.this가 전역객체 가리킴
}
innerFunc1();
// TO-BE
var self = this;//여전히 this는 outer함수를 호출한 객체를 가리키는상태.
//this를 self변수에 할당
var innerFunc2 = function() {
console.log(self); // this가 obj1가리킴.
};
innerFunc2();
}
};
obj1.outer();
var obj = {
outer: function() {
console.log(this); // obj
var innerFunc = () => {
console.log(this); // obj
};
innerFunc();
var innerFunc = function() {
console.log(this); // 전역객체
};
innerFunc();
}
}
obj.outer();
콜백함수 : 어떠한 함수에 메서드의 인자(매개변수)로 전달되는 함수
콜백 함수도 함수기 때문에 this는 전역 객체를 참조.
예외적으로 콜백 함수에 별도로 this를 지정한 경우는 그대상을 참조
// addListener 안에서의 this는 항상 호출한 주체의 element를 return하도록 설계되었음
// 따라서 this는 button을 의미함
document.body.innerHTML += '<button id="a">클릭</button>';
document.body.querySelector('#a').addEventListener('click', function(e) {
console.log(this, e);
});
생성자 함수를 통해 생성된 새 객체를 가리킴.
밑 예시에서는 Cat 함수로 생성될 각각의 객체(choco,nabi)를 참조
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