[JS] 유효범위, this 키워드,
아래 코드의 function declaration은 자바스크립트의 호이스팅에 해당된다.
함수가 먼저 호출된 후 선언되어도, 호이스팅 동작으로 무리없이 함수가 작동된다.
// functions declaration
calculateAge(1965);
function calculateAge(year) {
console.log(2022 - year); //
}
// this is hoisting
// function expression
retirement(1956);
var retirement = function (year) {
console.log(65 - (2016 - year));
} // Error occured: Type Error, 끌올이 안된다.
// hoisting only works for function declaration
function expression 표현은 declaration과 달리 호이스팅 동작이 되지 않는다.
먼저 retirement(1956)을 호출해도, 돌아오는 것은 Type Error 뿐이다.
age 변수를 먼저 호출한 뒤 값을 할당하면, Error 대신 undefined라는 문구만 나온다.
// variables
console.log(age);
var age = 23; // how hoisting works in Variables => undefined
// this age is stored as global execution context
foo();
function foo() {
console.log(age); >>> undefined
var age = 65; // this age is function execution context, so it s different with 'age' up there
console.log(age); >>> 65
}
console.log(age); >>> 23
foo 함수가 호이스팅에 의해 호출되어도
첫번째 console.log(age)는 undefined로 나온다. 이는 function execution context로 위의 23으로 할당된 age와는 별개임을 알 수 있다.
다음 줄에서 age에 값이 할당(defined)된 후 age를 출력하면 할당된 값이 나온다.
- Scope, 유효범우
//Lecture: Scoping
//Scoping answers the question 'where can we access a certain variable' ?
//Each new function creates a scope: the space / environment, in which the variables it defines are accessible
// First scoping example
var a = 'Hello!';
first();
function first() {
var b = 'Hi!';
//console.log(c) // Uncaught ReferenceError
second();
//var b = 'Hi!'; // if it stays in this location, it appears to be undefined at line 61
function second() {
var c = 'Hey!';
console.log(a + b + c); //line 61
}
}
first() 함수 내에 var b를 두 번 할당했다.(두번째 것은 주석처리함)
당연하게도 첫번째로 할당된 b는 second() 함수가 호출될 때 console.log에 정상 출력되지만,
(주석처리된) 두번째 b를 할당한다면 (second()가 호출된 후의 위치에서), console.log(a+b+c)에서 undefined로 출력된다. (선언은 됐기에 에러처리는 하지 않고, undefined라고 미할당 표시만 나타낸다)
// // Example to show the differece between execution stack and scope chain
var a = 'Hello!';
first();
function first() {
var b = 'Hi!';
second();
function second() {
var c = 'Hey!';
third() // it works by hoisting(function declaration)
}
}
function third() {
var d = 'Lim';
//console.log(c); // c is not defined which means func third's scope is different to stack execution
console.log(a + d); // this means, fun third()'s scope is a & d
}
third() 함수 내의 주석처리 된 c는 first() 함수 내 second() 함수에서 선언됐기에,
이는 third()함수와 유효범위가 달라 not defined 에러가 발생한다.
즉 third()함수의 유효범위 내에 존재하는 변수는 a와 c만 해당된다.
만약 second()함수 에서 third()의 호출 뿐만 아니라 선언까지 이뤄졌다면, 변수c 도 third() 함수의 유효범위에 들어오게 된다.
* point는 곧, '함수가 어디서 선언됐느냐' 이다.
- 'this' keyword
// object john
var place = 'busan'
var john = {
name: 'Bongju',
yearOfBirth: 1993,
place : 'busssan',
// function expression
calculateAge: function () {
console.log(this);
console.log(2020 - this.yearOfBirth); // 여기 this가 없으면 referencError 발생
// altho this function is inside of method,
// basically it is regular function
// so that's the reason why 'this'keyword is pointing at window object
function innerFunction() {
console.log(this.place); // 이것이 가리키는 것은 window.object
console.log(this)
// var place 가 calculateAge() 내에 위치하면 값이 할당되지 않은 것으로 나온다.
// 즉 여기서 this가 가리키는 것 역시 window.object이다.
}
innerFunction();
}
}
john.calculateAge(); //parenthesis is calling a function
var mike = {
name: 'Mike',
yearOfBirth: 2000
};
// method borrow
mike.calculateAge = john.calculateAge;
mike.calculateAge();
여기서도 함수의 선언위치가 중요한 역할을 한다.
우선, calculateAge() 함수는 john 오브젝트 내에 선언돼 있고
innerFunction() 함수는 calculateAge() 함수 내에서 선언됐다.
선언된 위치의 차이 때문에, innerFunction()의 this 키워드는 john object의 변수 대신 window의 변수를 가리키게 된다.(어렵구나)
스코프와 클로저 정리할것