변수의 유효범위 ( Scope )
- 🧐 변수가 어느 위치에서 유효한가?
- var는 function을 기준으로 let, const는 {}블록을 기준으로 함
- 변수 => var, let (ES6)
- 상수 => const (ES6)
// var scope
function a(){ // a() 함수 생성
var v_a = "a"; // 변수 v_a 초기화
function b(){ // a() 함수 안에 b() 함수를 생성
var v_b = "b"; // b() 함수 안에서 변수 v_b를 초기화
console.log(`b function : ${typeof (v)}, ${typeof (v_a)}, ${typeof (v_b)}`);
}
b(); // a() 함수 안에서 b() 함수를 호출
console.log(`a function : ${typeof (v)}, ${typeof (v_a)}, ${typeof (v_b)}`);
}
var v = "v"; // a() 함수를 바깥에서 변수 v 초기화
a(); // a() 함수를 호출
console.log(`all : ${typeof (v)}, ${typeof (v_a)}, ${typeof (v_b)}`);
/*
출력값
b function : string, string, string
a function : string, string, undefined
all : string, undefined, undefined
*/
// 코드로 확인할 수 있는 것!
// var의 유효범위는 function을 기준으로 한다.
// let scope
function test(){
for (let i=0; i<3; i++){
console.log(`${typeof (i)} inside the block: ${typeof (i)}`);
}
console.log(`${typeof (i)} inside the block: ${typeof (i)}`);
}
test();
console.log(`${typeof (i)} inside the block: ${typeof (i)}`);
/*
출력값
number inside the block: number
undefined inside the block: undefined
undefined inside the block: undefined
*/
// let을 var로 바꿔서 출력했을때
function test(){
for (let i=0; i<3; i++){
console.log(`${typeof (i)} inside the block: ${typeof (i)}`);
}
console.log(`${typeof (i)} inside the block: ${typeof (i)}`);
}
test();
console.log(`${typeof (i)} inside the block: ${typeof (i)}`);
/*
출력값
number inside the block: number
number inside the block: number
undefined inside the block: undefined
*/
변수 가림 현상 ( shadowing )
- 함수 바깥에서 선언한 변수와 이름이 같은 변수를 함수 안에서도 사용하는 경우, 함수 바깥에 있는 변수는 잠시 가려지는 현상
// 예시
// functino 밖에서만 선언했을때
function shadowing_example(){
console.log(`shadowing_example function : ${val}`);
val++;
}
var val = 0;
shadowing_example();
console.log(`function 밖의 val: ${val}`);
/*
출력값
shadowing_example function : 0
function 밖의 val: 1
*/
// function 안과 밖에서 같은 변수명으로 선언했을때
function shadowing_example(){
var val = 5;
console.log(`shadowing_example function : ${val}`);
val++;
}
var val = 0;
shadowing_example();
console.log(`function 밖의 val: ${val}`);
/*
출력값
shadowing_example function : 5
function 밖의 val: 0
*/
메서드와 this
메서드 |
함수가 객체의 속성값이 될 경우에 그 함수를 말함 |
this |
해당 함수 호출 방식에 따라 this에 바인딩되는 객체가 달라짐 |
// 메서드 예시
function f(){
console.log("f is called");
}
// 함수가 객체의 속성값이 되는 경우 => method(메서드)
let o = {name: "object", method: f};
f(); // 출력값: f is called
o.method(); // 출력값: f is called
// this 예시
function f(){
console.log(this)
}
let o = {name: "object", method: f};
// 전역에서 함수를 호출할때는 window객체에 바인드 됨
f();
/*
출력값
Window {window: Window, self: Window, …}
*/
// 객체 o에 바인드 되어있기때문에 this는 o객체를 출력함
o.method();
/*
출력값
{name: "object", method: ƒ}
*/
function f(){
console.log(this);
}
function setName(name){
this.name = name;
}
let o = {name: "object", method: f, setName: setName};
let o2 = {name: "", setName: setName};
o.setName("object1");
o2.setName("object2");
console.log(o, o2);
/*
출력값
{name: "object1", method: ƒ, setName: ƒ}
{name: "object2", setName: ƒ}
*/
클로저 ( closure )
- js의 함수와 그 함수가 선언될 때의 환경으로 이뤄짐
- 📌 클로저를 사용하는 이유!
-
- 다른 객체 지향 언어에 있는 private이나 public같은 개념을 구현 할 수 있다
// 예시
function makeCounterFunction(initVal){
let count = initVal;
function Increase(){
count++;
console.log(count);
}
return Increase;
}
let counter1 = makeCounterFunction(0);
let counter2 = makeCounterFunction(10);
counter1(); // 출력값: 1
counter2(); // 출력값: 11