Chapter 05 - norux/javascript_study GitHub Wiki
5. μ€ν 컨ν μ€νΈμ ν΄λ‘μ
- μ€ν 컨ν μ€νΈ(Execution Context)μ κ°λ
- νμ± κ°μ²΄(Activation Object)μ λ³μ κ°μ²΄(Variable Object)
- μ€μ½ν 체μΈ(Scope Chain)
- ν΄λ‘μ (Closure)
5.1 μ€ν 컨ν μ€νΈ κ°λ
- CμΈμ΄μ ν¨μ μ½μ€νκ³Ό μ μ¬ν κ°λ
- μ€ν κ°λ₯ν μ½λλ₯Ό νμννκ³ κ΅¬λΆνλ μΆμμ μΈ κ°λ λλ μ€ν κ°λ₯ν μλ°μ€ν¬λ¦½νΈ μ½λ λΈλ‘μ΄ μ€νλλ νκ²½
μ€ν 컨ν μ€νΈκ° νμ±λλ μΈκ°μ§ κ²½μ°
- μ μ μ½λ
- eval() ν¨μλ‘ μ€νλλ μ½λ
- ν¨μμμ μ½λλ₯Ό μ€νν κ²½μ°
μ€ν 컨ν μ€νΈμ μ μ
νμ¬ μ€νλλ 컨ν μ€νΈμμ μ΄ μ»¨ν μ€νΈμ κ΄λ ¨ μλ μ€ν μ½λκ° μ€νλλ©΄, μλ‘μ΄ μ»¨ν μ€νΈκ° μμ±λμ΄ μ€νμ λ€μ΄κ°κ³ μ μ΄κΆμ΄ κ·Έ 컨ν μ€νΈλ‘ μ΄λνλ€.
console.log("Global Context");
function ExContext1() {
console.log("EC1");
};
function ExContext2() {
ExContext1();
console.log("EC2");
};
ExContext2();
Question: μ€ν 컨ν μ€νΈμ μμ±κ³Όμ (ECμ μ€ν) κ·Έλ¦ΌμΌλ‘ 그리기!!
5.2 μ€ν 컨ν μ€νΈ μμ± κ³Όμ
- νμ± κ°μ²΄μ λ³μ κ°μ²΄
- μ€μ½ν 체μΈ
function execute(param1, param2) {
var a = 1, b = 2;
function func() {
return a + b;
}
return param1 + param2 + func();
}
execute(3, 4);
Question: μ€ν 컨ν μ€νΈλ₯Ό κ·Έλ €λ³΄μ!!
5.2.1 νμ± κ°μ²΄ μμ±
νμ± κ°μ²΄: ECκ° μμ±λ λ, ν΄λΉ 컨ν μ€νΈμμ μ€νμ νμν μ¬λ¬κ°μ§ μ 보λ₯Ό λ΄μ κ°μ²΄
5.2.2 arguments κ°μ²΄ μμ±
5.2.3 μ€μ½ν μ 보 μμ±
[ [scope]] νλ‘νΌν°λ‘ μ°Έμ‘°λλ©°, μ€μ½ν μ 보λ 리μ€νΈ ννλ₯Ό λκ³ μλ€.
5.2.4 λ³μ μμ±
EC λ΄λΆμμ μ¬μ©λλ μ§μλ³μκ° μμ±λλ€.
- μ°Έκ³ : νμ±κ°μ²΄μ λ³μκ°μ²΄λ κ°μ κ°μ²΄μ΄λ€.
λ³μμ μμ±κ³Ό μ΄κΈ°ν λ λΆλ¦¬λμ΄ μ΄λ£¨μ΄μ§λ€. μ¬κΈ°μλ μμ± λ§ μ΄λ£¨μ΄μ§λ―λ‘, μ§μ λ³μ a, bμλ undefinedκ° ν λΉλλ€. funcλ μμ±λ§ λλ€. μ΄κΈ°νλ ννμμ΄ μ€νλκΈ° μ κΉμ§λ μ΄λ£¨μ΄μ§μ§ μλλ€.
5.2.5 this λ°μΈλ©
λ§μ§λ§ λ¨κ³λ‘ this λ°μΈλ©μ΄ μ΄λ£¨μ΄μ§λ€.
5.2.6 μ½λ μ€ν
ECκ° μμ±λκ³ λ³μ κ°μ²΄κ° λ§λ€μ΄μ§ νμ μ½λμ μλ ννμλ€μ μ€νμ΄ μ΄λ£¨μ΄ μ§λ€. μ΄ κ³Όμ μμ μ΄κΈ°ν κ³Όμ μ΄ μΌμ΄λλ€.
- μ°Έκ³ : μ μ ECλ μΌλ° ECμ μ½κ° λ€λ₯΄λ€. arguments κ°μ²΄κ° μκ³ , μ μκ°μ²΄ νλλ§μ ν¬ν¨νλ μ€μ½ν 체μΈμ΄ μλ€.
Node.jsμμλ μ΅μμ μ½λκ° μ μμ½λκ° μλλ€.
//λΈλΌμ°μ var a = 10; b = 15; console.log(window.a); //10 console.log(window.b); //15 // //Node.js var a = 10; b = 15; console.log(global.a); //undefined console.log(global.b); //15
## 5.3 μ€μ½ν 체μΈ
CμΈμ΄λ for, ifλ¬Έμμμ {} λΈλ‘ μμ μ€μ½ν μ ν¨λ²μμ λ€μ΄κ°μ§λ§, μλ°μ€ν¬λ¦½νΈλ μ€μ§ **ν¨μλ§** μ ν¨λ²μμ λ¨μκ° λλ€.
[ [scope]] νλ‘νΌν°λ‘ κ° ν¨μ κ°μ²΄λ΄μμ μ°κ²° 리μ€νΈλ‘ κ΄λ¦¬λλ©°, μ΄λ₯Ό μ€μ½ν 체μΈμ΄λΌ νλ€.
| | μ€μ½ν μ²΄μΈ |
|:--:|:--------:|
| 3 | .... |
| 2 | λ³μκ°μ²΄ 2 |
| 1 | λ³μκ°μ²΄ 1 |
| 0 | λ³μκ°μ²΄ 0 |
[μ€μ½νμ²΄μΈ λ¦¬μ€νΈ]
κ° ν¨μλ [ [scope]] νλ‘νΌν°λ‘ μμ μ΄ μμ±λ ECμ μ€μ½ν 체μΈμ μ°Έμ‘°νλ€.
### 5.3.1 μ μ μ€ν 컨ν
μ€νΈμ μ€μ½ν 체μΈ
```javascript
var var1 = 1;
var var2 = 2;
Question: μ μ μ€ν 컨ν μ€νΈ κ·Έλ¦Ό κ·Έλ €λ³΄κΈ°
5.3.2 ν¨μλ₯Ό νΈμΆν κ²½μ° μμ±λλ μ€ν 컨ν μ€νΈμ μ€μ½ν 체μΈ
var var1 = 1;
var var2 = 2;
function func(){
var var1 = 10;
var var2 = 20;
}
func();
Question: μ€ν 컨ν μ€νΈ κ·Έλ¦Ό κ·Έλ €λ³΄κΈ°
μ€μ½ν μ²΄μΈ μ 리
- κ° ν¨μ κ°μ²΄λ [ [scope]]νλ‘νΌν°λ‘ νμ¬ μ»¨ν μ€νΈμ μ€μ½ν 체μΈμ μ°Έμ‘°νλ€.
- μλ‘μ΄ ECκ° μμ±λλ©΄, νμ¬ μ€νλλ ν¨μ κ°μ²΄μ [ [scope]]νλ‘νΌν°λ₯Ό 볡μ¬νκ³ μλ‘κ² μμ±λ λ³μκ°μ²΄λ₯Ό ν΄λΉ μ²΄μΈ μ μΌ μμ μΆκ°νλ€.
- μ€μ½ν μ²΄μΈ = νμ¬ μ€ν 컨ν μ€νΈμ λ³μκ°μ²΄ + μμ 컨ν μ€νΈμ μ€μ½ν 체μΈ
var value = 10;
function printValue() {
return value;
}
function printFunc(func) {
var value = 100;
console.log(func());
}
printFunc(printValue);
Question: μ ν¨μμ κ²°κ³Όλ μ΄λ»κ² λ κΉ? μ€ν 컨ν μ€νΈ κ·Έλ¦Ό κ·Έλ €λ³΄κΈ°
hint. κ° ν¨μκ° μ€νλ λμ μ€ν 컨ν μ€νΈκ° 무μμΈμ§λ₯Ό μκ°ν΄μΌ νλ€.
with ν€μλ
μλ°μ€ν¬λ¦½νΈμλ μ€μ½ν체μΈμ μ¬μ©μκ° μμλ‘ μμ ν μ μλ withλΌλ ν€μλκ° μλ€.
withλ evalκ³Ό ν¨κ», μ¬μ©νμ§ λ§μμΌ ν ν€μλμ΄λ€. "Pure javascript evil.."
with ν€μλλ νΉμ κ°μ²΄λ₯Ό [ [scope]]리μ€νΈ μ΅μλ¨μ μ¬λ¦¬λ μν μ νλ€.
.
νΈμ΄μ€ν
ν¨μμ μμ±κ³Όμ μ μ΄ν΄νλ€λ©΄, ν¨μμ νΈμ΄μ€ν μ μ΄ν΄ν μ μμ κ²μ΄λ€.
foo(); //TypeError bar(); //μ€νλ¨ var foo = function() { ... } function bar() { ... } var x = 1;
## 5.4 ν΄λ‘μ
```javascript
function outerFunc(){
var x = 10;
var innerFunc() = function (){
console.log(x);
}
return innerFunc;
}
var inner = outerFunc();
inner(); // 10
Question: κ·Έλ¦Ό κ·Έλ €λ³΄κΈ°
inner()κ° μ€νλ λ, μ΄λ―Έ outerFuncμ μ€ν 컨ν μ€νΈλ μ’ λ£λ νμ΄λ€. νμ§λ§, innerFuncμ μ€ν 컨ν μ€νΈμ μ€μ½ν체μΈμλ outerFuncμ λ³μκ°μ²΄λ λ¨μμκ² λλ€. μ΄κ²μ΄ ν΄λ‘μ λΌλ κ°λ μ΄λ€.
- ν΄λ‘μ : μ΄λ―Έ μλͺ μ£ΌκΈ°κ° λλ μΈλΆν¨μμ λ³μλ₯Ό μ°Έμ‘°νλ ν¨μ
- μμ λ³μ: ν΄λ‘μ λ‘ μ°Έμ‘°λλ μΈλΆλ³μ(μ¦, μ μμ μμλ x)
function outerFunc(arg1, arg2) {
var local = 8;
function innerFunc(innerArg){
console.log((arg1 + arg2)/innerArg + local));
}
return innerFunc;
}
var exam1 = outerFunc(2, 4);
exam1(2);
}
Question: μ κ²°κ³Ό μμΈ‘ν΄λ³΄κΈ°
5.4.2 ν΄λ‘μ μ νμ©
μ±λ₯, μμμ μΈ λ©΄μμ μ½κ° μν΄λ₯Ό λ³Ό μ μμΌλ―λ‘ λ¬΄μ°¨λ³μ μΌλ‘ μ¬μ©ν΄μλ μλλ€.
ν¨μν νλ‘κ·Έλλ°μμ λ§μ΄ νμ©λλ€. 7μ₯μμ μμΈν μ€λͺ μ νλ€.
5.4.2.1 νΉμ ν¨μμ μ¬μ©μκ° μ μν κ°μ²΄μ λ©μλ μ°κ²°νκΈ°
function HelloFunc( func ) {
this.greeting = "hello";
}
//HelloFunc μμ±μ ν¨μμ call λ©μλ λμ μμ±
HelloFunc.prototype.call = function( func ) {
func ? func(this.greeting) : this.func(this.greeting);
}
function saySomething( obj, methodName, name ) {
return ( function( greeting ) {
return obj[methodName]( greeting, name );
} );
}
// μμ±μν¨μ newObj()
function newObj( obj, name ) {
obj.func = saySomething( this, "who", name );
return obj;
}
// who λ©μλ λμ μμ±
newObj.prototype.who = function( greeting, name ) {
console.log( greeting + " " + name || "everyone" ) );
}
var objHello = new HelloFunc();
var obj1 = new newObj( objHello, "zzoon" );
obj1.call();
//μΆλ ₯κ²°κ³Ό
//hello zzoon
5.4.2.2 ν¨μμ μΊ‘μν
I am XXX, I live in XXX, I'm XX years old
- XXXμλ μ¬μ©μμ μ λ ₯μ λ°μ μ λ¬Έμ₯μ λ§λ€κΈ° μν΄μ, λ°°μ΄μ μ΄μ©νμ¬ λ§λ€ μ μλ€.
var bufAry = [
"I am ",
"",
", I live in ",
"",
", I'm ",
"",
" years old"
];
//μ΄ν bufAry[1], bufAry[3], bufAry[5]μ μ¬μ©μμ μΈνμ λ£μ
μμ κ°μ μ½λλ bufAryκ° μ μλ³μμ΄κΈ° λλ¬Έμ, μΈλΆμ λ ΈμΆλμ΄ μλ€λ λ¨μ μ΄ μλ€. μ΄ μ½λλ₯Ό ν΄λ‘μ λ₯Ό νμ©νμ¬ λ°κΎΈλ©΄ λ€μκ³Ό κ°λ€.
var getCompletedString = ( function() {
var bufAry = [
"I am ",
"",
", I live in ",
"",
", I'm ",
"",
" years old"
];
return ( function( name, city, age) {
bufAry[1] = name;
bufAry[3] = city;
bufAry[5] = age;
} );
} )();
var str = getCompletedString( "heebum", "seoul", 19 );
Question: μ€ν 컨ν μ€νΈ κ·Έλ¦Ό κ·Έλ €λ³΄κΈ°
5.4.2.3 setTimeout()μ μ§μ λλ ν¨μμ μ¬μ©μ μ μ
setTimeout()ν¨μ: ν¨μλ₯Ό μΈμλ‘ λκ²¨μ£Όμ΄ μ€ννλ€. νμ§λ§, ν¨μμ μΈμλ₯Ό ν¨κ» λ겨주μ§λ λͺ»νλ€. μΈμλ₯Ό λ겨주기 μν΄ ν΄λ‘μ ν¨μλ₯Ό μ΄μ©νλ€.
function callLater( obj, a, b) {
return (function(){
obj["sum"] = a + b;
});
var sumObj = {
sum : 0
}
var func = callLater( sumObj, 1, 2 );
setTimeout( func, 500); //0.5μ΄ ν func() ν¨μ (ν΄λ‘μ ) μ€ν
5.4.3 ν΄λ‘μ λ₯Ό νμ©ν λ, μ£Όμμ¬ν
5.4.3.1 ν΄λ‘μ μ νλ‘νΌν° κ°μ μ°κΈ° κ°λ₯νλ―λ‘, κ·Έ κ°μ΄ μ¬λ¬λ² νΈμΆ λ λ νμ λ³ν μ μμμ μ μν΄μΌ νλ€.
5.4.3.2 νλμ ν΄λ‘μ κ° μ¬λ¬ ν¨μ κ°μ²΄μ μ€μ½ν 체μΈμ λ€μ΄κ° μλ κ²½μ°λ μλ€.
function func() {
var x = 1;
return {
func1 : function(){ console.log( ++x ); }
func2 : function(){ console.log( ~x ); }
};
}
var exam = func();
exam.func1();
exam.func2();
5.4.3.3 루ν μμμ ν΄λ‘μ λ₯Ό νμ©ν λλ μ£ΌμνλΌ
function countSeconds( howMany ) {
for( var i = 1; i <= howMany; i++ ) {
setTimeout( function() { console.log( i ); }, i * 1000 );
}
}
countSeconds( 3 );
μμ μμ λ 1, 2, 3 μ 1μ΄ κ°κ²©μΌλ‘ μΆλ ₯νλ μμ μ§λ§, 4, 4, 4 κ° 1μ΄ κ°κ²©μΌλ‘ μΆλ ₯λλ€. setTimeoutμ μΈμλ‘ λ€μ΄κ°λ μ΅λͺ ν¨μλ μμ λ³μ iλ₯Ό μ°Έμ‘°νλλ°, μ΄ ν¨μκ° μ€νλλ μμ μ countSeconds() ν¨μμ μ€νμ΄ μ’ λ£λ μ΄ν μ΄κΈ° λλ¬Έμ μμ λ³μ iλ μ΄λ―Έ 4κ° λ μνμΈ κ²μ΄λ€.
HB's Guess: λΉλκΈ° νλ‘κ·Έλλ°μΌλ‘ μμ© ν μ μμ κ² κ°μ