ABOUT ME

Today
Yesterday
Total
  • [TIL] 3주차 : 실행컨텍스트, 호이스팅, this
    이노베이션캠프/Js 문법 종합반 2023. 5. 24. 19:57

    * 실행컨테스트(스코프, 변수, 객체, 호이스팅)

     

    1. 실행컨테스트

    - 실행할 코드에 제공할 환경 정보를 모아놓은 객체

     

    1) 하는 일

    (1) 선언된 변수를 위로 끌어올림(호이스팅)

    (2) 외부 환경 정보를 구성

    (3) this 값을 설정함

     

    2) 콜스택(call stack)

    (1) stack

    - LIFO : Last in, first out // 가장 늦게 들어간 게 가장 먼저 나옴

    <-> Queue(큐) : FIFO, First in First out // 가장 먼저 들어간 게 가장 먼저 나옴

     

    (2) 콜스텍

    동일 환경에 있는 코드를 실행할 때 필요한 환경 정보들을 모아 컨텍스트를 구성하고 이것을 위에서 설명드린 ‘스택’의 한 종류인 "콜스택"에 쌓아올린다는 것.

     

    Js는 이러한 방식으로 코드의 순서를 보장함.

     

    (3) 컨테스트의 구성 (여러가지가 있지만, 우리는 함수만 생각하면 됨)

    - 전역공간

    - eval() 함수

    - 함수(우리가 흔히 실행컨텍스트를 구성하는 방법)

     

    - 실행컨텍스트 구성 예시코드

    // ---- 1번
    var a = 1;
    function outer() {
    	function inner() {
    		console.log(a); //undefined
    		var a = 3;
    	}
    	inner(); // ---- 2번
    	console.log(a);
    }
    outer(); // ---- 3번
    console.log(a);

    - 실행컨텍스트 구성 순서

    위의 코드는 아래순서로 진행됨

    코드실행 → 전역(in) → 전역(중단) + outer(in) → outer(중단) + inner(in) → inner(out) + outer(재개) → outer(out) + 전역(재개) → 전역(out) → 코드종료

    +) 결국은 특정 실행 컨텍스트가 생성되는(또는 활성화되는) 시점이 콜 스택의 맨 위에 쌓이는(노출되는) 순간을 의미하구요. 곧, 현재 실행할 코드에 해당 실행 컨텍스트가 관여하게 되는 시점을 의미한다고 받아들여주시면 정확합니다! 👍👍

     


    실행컨텍스트, 즉 객체안에는 뭐가 들어 있을까?

     

    1. 실행 컨텍스트 객체의 실체(=담기는 정보)

    1) VariableEnvironment(VE)

    - 식별자 정보를 가지고 있음

    var a = 3 일 경우 var a를 가지고 있음

    외부환경 정보를 가지고 있음

    선언 시점 LE의 snapshot(처음 생성됐을 때의 모습)

     

    2) LexicalEnvironment(LE)

    - VE와 LE는 똑같음. 다만 LE는 변경사항을 실시간 반영함

    - 그러니까, 둘이 처음 생겼을 때는 똑같으나 LE는 계속 업데이트가 됨. VE는 처음의 모습(snapshot)을 계속 가지고 있음

     

    3) ThisBinding

    - This가 func안에서 어떤 기능을 할지 결정해주는 것

     

    2. VE, LE의 개요

    1) VE vs LE
    - 둘은 완벽하게 동일

    - 하지만 VE는 스냅샷을 유지, LE는 실시간으로 변경사항을 계속해서 반영

    +) 결국, 실행 컨텍스트를 생성할 때, VE에 정보를 먼저 담은 다음, 이를 그대로 복사해서 LE를 만들고 이후에는 주로 LE를 활용한답니다.

     

    2) LE - environmentRocord(=record)와 호이스팅

    - 현재 컨텍스트와 관련된 코드의 식별자 정보들이 저장됨

    기록된다 라고 이해하면 record라는 말과 일맥상통!

    - 수집 대상 정보 : 함수에 지정된 매개변수 식별자, 함수 자체, var로 선언된 변수 식별자 등

    - 컨텍스트 내부를 처음부터 끝까지 순서대로 훑어가며 수집

    -> 말 그대로 순서대로 수집을 얘기함. 코드가 실행된다고 하지는 않음!

     

    (1) 호이스팅(hoisting; hoist: 끌어올리다)

    - 식별자를 수집할 때 나오는 개념!

    - 변수 정보 수집 과정을 이해하기 쉽게 설명한 가상 개념’

     

    (2) 호이스팅 규칙

    ① 매개변수 및 변수는 선언부를 호이스팅 한다.

    ② 함수 선언은 전체를 호이스팅합니다.

    - 모든 함수가 호이스팅 되는 것은 아님

    -> 함수 정의 3가지 방식

    // 함수 선언문. 함수명 a가 곧 변수명
    // function 정의부만 존재, 할당 명령이 없는 경우
    function a () { /* ... */ }
    a(); // 실행 ok
    
    // 함수 표현식. 정의한 function을 별도 변수에 할당하는 경우
    // (1) 익명함수표현식 : 변수명 b가 곧 변수명(일반적 case에요)
    var b = function () { /* ... */ }
    b(); // 실행 ok
    
    // (2) 기명 함수 표현식 : 변수명은 c, 함수명은 d / 거의 안 함
    // d()는 c() 안에서 재귀적으로 호출될 때만 사용 가능하므로 사용성에 대한 의문
    var c = function d () { /* ... */ } 
    c(); // 실행 ok
    d(); // 에러!

    -> 함수 선언문과 함수 표현식은 호이스팅 때 많이 다름

    // 함수 선언문은 전체를 hoisting
    function sum (a, b) { // 함수 선언문 sum
    	return a + b;
    }
    
    // 변수는 선언부만 hoisting
    
    var multiply; 
    
    console.log(sum(1, 2));
    console.log(multiply(3, 4));
    
    multiply = function (a, b) { // 변수의 할당부는 원래 자리
    	return a + b;
    };

    * 함수 선언문을 주의해야 하는 이유

    ...
    
    console.log(sum(3, 4));
    
    // 함수 선언문으로 짠 코드
    // 100번째 줄 : 시니어 개발자 코드(활용하는 곳 -> 200군데)
    // hoisting에 의해 함수 전체가 위로 쭉!
    function sum (x, y) {
    	return x + y;
    }
    
    ...
    ...
    
    var a = sum(1, 2);
    
    ...
    
    // 함수 선언문으로 짠 코드
    // 5000번째 줄 : 신입이 개발자 코드(활용하는 곳 -> 10군데)
    // hoisting에 의해 함수 전체가 위로 쭉!
    function sum (x, y) {
    	return x + ' + ' + y + ' = ' + (x + y);
    }
    
    ...
    
    var c = sum(1, 2);
    
    console.log(c);

    - 함수 표현식이었다면?

    ...
    
    console.log(sum(3, 4));
    
    // 함수 표현식으로 짠 코드
    // 함수 선언부만 위로 쭉!
    // 이 이후부터의 코드만 영향을 받아요!
    var sum = function (x, y) {
    	return x + y;
    }
    
    ...
    ...
    
    var a = sum(1, 2);
    
    ...
    
    // 함수 표현식으로 짠 코드
    // 함수 선언부만 위로 쭉!
    // 이 이후부터의 코드만 영향을 받아요!
    var sum = function (x, y) {
    	return x + ' + ' + y + ' = ' + (x + y);
    }
    
    ...
    
    var c = sum(1, 2);
    
    console.log(c);

    - 문제가 없었다^^

    표현식을 많이 쓰자~

     


    이제 outer 에 대해 배워보자!

    잠깐 배우고 있는 것 정리

    - 실행 컨텍스트 실행할 코드에 제공할 환경 정보들을 모아놓은 객체이다.
    - 그 객체 안에는 3가지가 존재한다.
    ✓ VariableEnvironment
    ✓ LexicalEnvironment
    ✓ ThisBindings
    - VE와 LE는 실행컨텍스트 생성 시점에 내용이 완전히 같고, 이후 스냅샷 유지 여부가 다르다.
    - LE는 다음 2가지 정보를 가지고 있다.
    ✓ record(=environmentRecord) ← 이 record의 수집과정이 hoisting
    ✓ outer(=outerEnvironmentReference)

    * outerEnvironmentReference (outer)

    1. 스코프

    - 식별자에 대한 유효범위(변수가 어디까지 영향을 미치냐)

    2. 스코프체인

    - 식별자의 유효범위를 안에서부터 바깥으로 차례로 검색해 나가는 것

    https://jess2.xyz/JavaScript/scope-chain-closure/

    - outer는 현재 호출된 함수가 선언될 당시(이 말이 중요!)의 LexicalEnvironment를 참조(그 당시의 환경 정보를 저장함)함.

    // 아래 코드를 여러분이 직접 call stack을 그려가며 scope 관점에서 변수에 접근해보세요!
    // 어려우신 분들은 강의를 한번 더 돌려보시기를 권장드려요 :)
    var a = 1;
    var outer = function() {
    	var inner = function() {
    		console.log(a); // 이 값은 뭐가 나올지 예상해보세요! 이유는 뭐죠? scope 관점에서!
    		var a = 3;
    	};
    	inner();
    	console.log(a); // 이 값은 또 뭐가 나올까요? 이유는요? scope 관점에서!
    };
    outer();
    console.log(a); // 이 값은 뭐가 나올까요? 마찬가지로 이유도!

    - inner 함수 안의 console.log(a)가 가장 먼저 나올 것! 여기의 값은 undefined . a에 할당된 값이 아직 없음. inner 함수가 먼저 실행이 될 텐데, console.log(a)가 찍히기 전 아직 된 것이 없음

    - outer 함수 내의 console.log(a) 가 두번째로 실행됨. 여기서는 1 이 나옴. 왜 3 이 아니냐? inner()함수는 이미 스텍에서 사라짐. 자신의 할일을 끝내고 나가버림. 대신 outer 함수의 outer, 즉, 전역함수 내의 a = 1이 남아있음. 그래서 1이 찍히는 거임.

    - 마지막으로 가장 밖, 아래에 있는 console.log(a) 의 실행결과로 1이 나옴. outer 함수도 스텍에서 빠져나가고 마지막으로 남은 전역에서 a = 1이라고 할당을 해주었으니까!

     

    +)

    각각의 실행 컨텍스트는 LE 안에 record와 outer를 가지고 있고, outer 안에는 그 실행 컨텍스트가 선언될 당시의 LE정보가 다 들어있으니 scope chain에 의해 상위 컨텍스트의 record를 읽어올 수 있다.


    * 상황에 따라 달라지는 this (전역공간 this 함수 this 메서드 this)

    - 지금 하려는 것이 뭔지 다시 리마인딩

    - 실행 컨텍스트 실행할 코드에 제공할 환경 정보들을 모아놓은 객체이다.
    - 그 객체 안에는 3가지가 존재한다.
    ✓ VariableEnvironment
    ✓ LexicalEnvironment
    ✓ ThisBindings

    1. 전역환경의 this

    1) runtime (run+time)

    - 코드가 돌아가는 그 환경

    (1) 노드

    (2) 브라우저

     

    => 전역환경에서 this 는 -> 노드(global 객체), 브라우저(window 객체)

     

     

    2. 메서드로서 호출할 때 그 메서드 내부에서의 this

    1) 함수 vs 메서드

    독립성 차이. 함수는 독립성이 있음. 메서드는 독립성이 없음

    함수명(); // 함수는 독립적 수행 가능
    객체.메서드명(); // 메서드는 자신을 호출한 대상 객체에 대한 동작을 수행함

    - 즉, 함수의 this는 전역(주체가 없기 때문에), 메서드의 this는 호출의 주체가 됨. 

     

    2) this의 할당

    // CASE1 : 함수
    // 호출 주체를 명시할 수 없기 때문에 this는 전역 객체를 의미해요.
    var func = function (x) {
    	console.log(this, x);
    };
    func(1); // Window { ... } 1
    
    // CASE2 : 메서드
    // 호출 주체를 명시할 수 있기 때문에 this는 해당 객체(obj)를 의미해요.
    // obj는 곧 { method: f }를 의미하죠?
    var obj = {
    	method: func,
    };
    obj.method(2); // { method: f } 2

    - browser에서 실행되고 있음을 가정

     

    3) 함수로서의 호출과 메서드로서의 호출 구분 기준 : . []

    var obj = {
    	method: function (x) { console.log(this, x) }
    };
    obj.method(1); // { method: f } 1
    obj['method'](2); // { method: f } 2

    4) 메서드 내부에서의 this

    var obj = {
    	methodA: function () { console.log(this) },
    	inner: {
    		methodB: function() { console.log(this) },
    	}
    };
    
    obj.methodA();             // this === obj
    obj['methodA']();          // this === obj
    
    obj.inner.methodB();       // this === obj.inner
    obj.inner['methodB']();    // this === obj.inner
    obj['inner'].methodB();    // this === obj.inner
    obj['inner']['methodB'](); // this === obj.inner

    보면서 익혀보기

     

    3. 함수로서 호출할 때 그 함수 내부에서의 this

    1) 함수 내부에서의 this

    - this가 지정되지 않음(호출 주체를 알 수 없으므로)

    - 따라서, 함수로서 독립적으로 호출할 때는 this는 항상 전역객체를 가리침

     

    2) 메서드의 내부함수에서의 this

    -> 메서드의 내부함수에서의 this

    예외없음! 메서드 내부라고 해도 전역객체를 가리킴

    var obj1 = {
    	outer: function() {
    		console.log(this); // (1)
    		var innerFunc = function() {
    			console.log(this); // (2), (3)
    		}
    		innerFunc();
    
    		var obj2 = {
    			innerMethod: innerFunc
    		};
    		obj2.innerMethod();
    	}
    };
    obj1.outer();

    {outer: f}

    window{...}

    {innerMethod: f}

     

    3) 메서드의 내부 함수에서의 this 우회

    - this에 대해 이해는 되지만, 개발자 입장에서는 참 불편함. 그렇기에 우회하는 방법들이 있음

     

    (1) 변수를 활용하는 방법

    내부스코프에 이미 존재하는 this를 별도의 변수(ex. self)에 할당하는 방법

    var obj1 = {
    	outer: function() {
    		console.log(this); // (1) outer
    
    		// AS-IS
    		var innerFunc1 = function() {
    			console.log(this); // (2) 전역객체
    		}
    		innerFunc1();
    
    		// TO-BE
    		var self = this;
    		var innerFunc2 = function() {
    			console.log(self); // (3) outer
    		};
    		innerFunc2();
    	}
    };
    
    // 메서드 호출 부분
    obj1.outer();

    // AS-IS : 기존것

    // TO-BE : 이후것

     

    (2) 화살표 함수

    함수 내부에서 this가 전역객체를 바라보는 문제 때문에 화살표 함수를 도입함! 일반함수와 화살표함수의 가장 큰 차이가 this binding 여부임

    var obj = {
    	outer: function() {
    		console.log(this); // (1) obj
    		var innerFunc = () => {
    			console.log(this); // (2) obj
    		};
    		innerFunc();
    	}
    }
    
    obj.outer();

    this binding 과정이 없기 때문에 두번재 console.log(this)도 이어져서 obj가 되는 것임.

     

    (3) 콜백함수 호출 시 그 함수 내의 this

    -> 콜백함수

    어떤 함수를 호출 할 때, 매개변수로 들어가는 함수

    콜백함수도 함수다!

     

    // 별도 지정 없음 : 전역객체
    setTimeout(function () { console.log(this) }, 300);
    
    // 별도 지정 없음 : 전역객체
    [1, 2, 3, 4, 5].forEach(function(x) {
    	console.log(this, x);
    });
    
    // 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);
    });

    로직보다는, this의 상태를 이해해보자!

     

    결국 함수로서의 호출이기 때문에 this를 다 잃어버리게 됨(전역객체를 바라보게 된다)

    단, 예외는 있다

    콜백함수에 별도로 this를 지정한 경우! (addEventListener 경우. 이건 우리가 하는 게 아니고, 이걸 만든 개발자가 지정해놓음)

     

    (4) 생성자 함수 내부에서의 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는 항상 인스턴스를 지칭한다! 새로운 인스턴스를 만들때마다 this는 달라진다

     


    * 명시적 this 바인딩 및 유사배열객체

    1. 명시적 this 바인딩

    - 상황별 규칙을 깨고 this에 별도의 값을 명시적으로 지정하는 것

    - call, apply, bind 메서드와 함께 얘기해보자~

     

    1) call 

    - 전역객체를 바라보는 경우에 명시적 바인딩

    var func = function (a, b, c) {
    	console.log(this, a, b, c);
    };
    
    // no binding
    func(1, 2, 3); // Window{ ... } 1 2 3
    
    // 명시적 binding
    // func 안에 this에는 {x: 1} binding돼요
    func.call({ x: 1 }, 4, 5, 6}; // { x: 1 } 4 5 6

    - this로서 바인딩하고 싶은 객체를 앞에 넣어주면 됨( ex. {x:1})

     

    - 호출객체가 존재하는 상황에서 명시적 바인딩

    var obj = {
    	a: 1,
    	method: function (x, y) {
    		console.log(this.a, x, y);
    	}
    };
    
    obj.method(2, 3); // 1 2 3
    obj.method.call({ a: 4 }, 5, 6); // 4 5 6

     

    2) apply

    - call과 완전히 똑같음. 뒤에 있는 매개변수만 대괄호([])로 잘 묶어주면 됨

    var func = function (a, b, c) {
    	console.log(this, a, b, c);
    };
    func.apply({ x: 1 }, [4, 5, 6]); // { x: 1 } 4 5 6
    
    var obj = {
    	a: 1,
    	method: function (x, y) {
    		console.log(this.a, x, y);
    	}
    };
    
    obj.method.apply({ a: 4 }, [5, 6]); // 4 5 6

     

    3) 유사배열 객체

    - 유사배열객체

    : 배열과 유사한 형태의 객체

    : 조건 (배열과 유사해야하므로, 배열의 특징이 조건이됨)

    (1) 반드시 length가 필요!!

    (2) index번호가 0부터 시작해서 1씩 증가해야함. 이건 꼭 그래야하는 건 아닌데, 이렇게 안하면 예상치 못한 결과가 생김

    //객체에는 배열 메서드를 직접 적용할 수 없어요.
    //유사배열객체에는 call 또는 apply 메서드를 이용해 배열 메서드를 차용할 수 있어요.
    var obj = {
    	0: 'a',
    	1: 'b',
    	2: 'c',
    	length: 3
    };
    Array.prototype.push.call(obj, 'd');
    console.log(obj); // { 0: 'a', 1: 'b', 2: 'c', 3: 'd', length: 4 }
    
    var arr = Array.prototype.slice.call(obj);
    console.log(arr); // [ 'a', 'b', 'c', 'd' ]

    - 실제 배열의 메서드를 쓸 수 없음

    - 하지만, 비슷하게 쓸 수는 있음. call을 통해!

     

    (3) Array.from

    - ES6에서 등장한 새로운 메서드

    - this를 활용하는게 편법이다보니.. 이를 위해 새로운 메서드가 만들어짐

    - 객체를 배열로 만들어주는!

     


    * call apply bind 응용

     

    1. 응용 이어서

    1) 생성자 내부에서 다른 생성자를 호출(공통된 내용의 반복 제거)

    function Person(name, gender) {
    	this.name = name;
    	this.gender = gender;
    }
    function Student(name, gender, school) {
    	Person.call(this, name, gender); // 여기서 this는 student 인스턴스!
    	this.school = school;
    }
    function Employee(name, gender, company) {
    	Person.apply(this, [name, gender]); // 여기서 this는 employee 인스턴스!
    	this.company = company;
    }
    var kd = new Student('길동', 'male', '서울대');
    var ks = new Employee('길순', 'female', '삼성');

    Person 이라는 생성자 함수를 별도로 빼서 '구조화'에 도움을 줌

     

    2) 여러 인수를 묶어 하나의 배열로 전달할 때 apply 사용 가능

    //비효율
    var numbers = [10, 20, 3, 16, 45];
    var max = min = numbers[0];
    numbers.forEach(function(number) {
    	// 현재 돌아가는 숫자가 max값 보다 큰 경우
    	if (number > max) {
    		// max 값을 교체
    		max = number;
    	}
    
    	// 현재 돌아가는 숫자가 min값 보다 작은 경우
    	if (number < min) {
    		// min 값을 교체
    		min = number;
    	}
    });
    
    console.log(max, min);
    //효율
    var numbers = [10, 20, 3, 16, 45];
    var max = Math.max.apply(null, numbers);
    var min = Math.min.apply(null, numbers);
    console.log(max, min);
    
    // 펼치기 연산자(Spread Operation)를 통하면 더 간편하게 해결도 가능해요
    const numbers = [10, 20, 3, 16, 45];
    const max = Math.max(...numbers);
    const min = Math.min(...numbers);
    console.log(max min);

    - 응 max나 min 은 그냥 Spread Operation 쓰는게 좋긴 함 /  ...Arr

     

    2. Bind 메서드

    - call과 비슷해보이나, 즉시 호출하는 call과 다르게 넘겨받은 this 및 인수들을 바탕으로 새로운 함수를 반환하는 메서드임

    - 사용목적 : 함수에 this를 미리 적용, 부분 적용 함수 구현 때 용이

    - 예시

    var func = function (a, b, c, d) {
    	console.log(this, a, b, c, d);
    };
    func(1, 2, 3, 4); // window객체
    
    // 함수에 this 미리 적용
    var bindFunc1 = func.bind({ x: 1 }); // 바로 호출되지는 않아요! 그 외에는 같아요.
    bindFunc1(5, 6, 7, 8); // { x: 1 } 5 6 7 8
    
    // 부분 적용 함수 구현
    var bindFunc2 = func.bind({ x: 1 }, 4, 5); // 4와 5를 미리 적용
    bindFunc2(6, 7); // { x: 1 } 4 5 6 7
    bindFunc2(8, 9); // { x: 1 } 4 5 8 9

    - 사용목적 + : bind 메서드를 적용해서 새로 만든 함수는 name 프로퍼티에 'bound'(bind의 수동태)라는 접두어가 붙임. 추적이 쉬워짐!

    var func = function (a, b, c, d) {
    	console.log(this, a, b, c, d);
    };
    var bindFunc = func.bind({ x:1 }, 4, 5);
    
    // func와 bindFunc의 name 프로퍼티의 차이를 살펴보세요!
    console.log(func.name); // func
    console.log(bindFunc.name); // bound func

    3. 상위 컨텍스트의 this를 내부함수나 콜백 함수에 전달하기

    1) 내부함수

    var obj = {
    	outer: function() {
    		console.log(this); // obj
    		var innerFunc = function () {
    			console.log(this);
    		};
    
    		// call을 이용해서 즉시실행하면서 this를 넘겨주었습니다
    		innerFunc.call(this); // obj
    	}
    };
    obj.outer();

    self를 통한 우회법(위에 참고)보다 call, apply, bind를 사용하면 더 깔끔하게 처리 가능함. 이러헤 사용하기~

    var obj = {
    	outer: function() {
    		console.log(this);
    		var innerFunc = function () {
    			console.log(this);
    		}.bind(this); // innerFunc에 this를 결합한 새로운 함수를 할당
    		innerFunc();
    	}
    };
    obj.outer();

    bind 사용

     

    2) 콜백함수

    - 콜백함수도 함수이기때문에, 함수가 인자로 전달될 때는 함수 자체로 전달됨. 즉 this가 유실됨

    - bind 메서드를 이용해 this를 편리하게 변경하기

    var obj = {
    	logThis: function () {
    		console.log(this);
    	},
    	logThisLater1: function () {
    		// 0.5초를 기다렸다가 출력해요. 정상동작하지 않아요.
    		// 콜백함수도 함수이기 때문에 this를 bind해주지 않아서 잃어버렸어요!(유실)
    		setTimeout(this.logThis, 500);
    	},
    	logThisLater2: function () {
    		// 1초를 기다렸다가 출력해요. 정상동작해요.
    		// 콜백함수에 this를 bind 해주었기 때문이죠.
    		setTimeout(this.logThis.bind(this), 1000);
    	}
    };
    
    obj.logThisLater1();
    obj.logThisLater2();

     

    3) 화살표 함수의 예외사항

    - 화찰표 함수는 실행 컨텍스트 생성 시, this를 바인딩하는 과정이 제외됨

    - 이 함수 내부에는 this의 할당과정이 아예 없음. 접근코자하면 스코프체인상 가장 가까운 this에 접근하게 됨

    - this 우회, call, apply, bind보다 편리한 방법임

    var obj = {
    	outer: function () {
    		console.log(this);
    		var innerFunc = () => {
    			console.log(this);
    		};
    		innerFunc();
    	};
    };
    obj.outer();

    * 코테 관련 참고 문서

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in

     

    for...in - JavaScript | MDN

    The for...in statement iterates over all enumerable string properties of an object (ignoring properties keyed by symbols), including inherited enumerable properties.

    developer.mozilla.org

     

     

Designed by Tistory.