[내배캠] 4/24 8일차

초이·2024년 4월 24일
0

Scope

: 식별자에 대한 유효범위를 의미한다. 대부분의 언어에 존재한다.

Scope chain

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

outerEnvironmentReference(=outer)

: 스코프 체인이 가능토록 하는 것.(외부 환경의 참조정보)

callstack에 쌓일때 실행하고 있는 실행 컨텍스트의 상위 컨텍스트의 record 불러올수있다.

2. This

전역환경에서 this는 현재 돌아가는 환경(runtime)을 가르킨다. (node, window)

메서드vs함수

  • 차이점 : 독립성이 차이점이다.
  • 함수 : 그 자체로도 실행이 된다.
  • 메서드: 어떤 객체에서 불러와야된다. 실행의 주체가 있어야된다.

함수의 this : 독립적으로 호출할 때, 호출 주체는 알수가없다. 전역객체를 의미.

메서드의 this : 호출한 주체를 명시할 수 있기 때문에 호출된 주체가 this가 된다. > (점(.) 또는 대괄호([])로 주체를 알 수있다.)

var obj1 = {
	outer: function() {
		console.log(this); 
		var innerFunc = function () {
			console.log(this); 
		};
		innerFunc(); //함수로써 호출(객체x) this : window
		
		var = obj2 = {
			innerMethod: innerFunc,
		};
		obj2.innerMethod(); //obj2 객체에서 호출 this : obj2
	},
};
obj1.outer(); //객체 안에 있는 outer를 실행. this : obj1

this 우회 방법

1. 변수를 활용하는 방법

: 내부 스코프에 이미 존재하는 this를 별도의 변수에 할당하는 방법

var self = this;
var inner = function() {
	console.log(self);
};
inner(); // self 값인 window가 출력된다.

2. 화살표 함수

: this를 바인딩 하지 않는 함수로써 화살표 함수 안에 있는 this는 이전의 값이 유지가 된다.

💡 **일반 함수와 화살표 함수의 가장 큰 차이점은?** >this 바인딩이 되지 않는 것.

3. 콜백 함수 호출 시 그 함수 내부에서의 this

: 콜백 함수도 함수로써의 호출이라서 this가 전역객체를 바라본다.

단, 예외가 있다. 콜백 함수에 별도로 this를 지정한 경우에만 this가 상위객체를 바인딩한다. > addListener 안에서의 this는 호출한 주체의 element를 reutrn하도록 설계되어있다.(프로그램 내부적으로)

4. 생성자 함수 내부에서의 this

  • 생성자 : 구체적인 인스턴스를 만들기 위한 일종의 틀
var Cat = function (name, age) { //생성자 함수
	this.bark = 'meow';
	this.name = name;
	this.age = age;
}

var nabi = new Cat('nabi', 2); //this : nabi

명시적 this 바인딩

: 위에서 정리한 규칙에 따라 자동으로 부여되는 this를 깨고 별도의 값을 저장하는 방법이 있다.

  • call
  • apply
  • bind

1. call 메서드

let func = function (a) {
	console.log(this, a);
}

//명시적 바인딩 하지 않은 것
func(1); // window 1

//명시적 바인딩
func.call({x:1}, 1}; // {x:1} 1
let obj = {
	a: 1,
	method: function (x) {
		console.log(this.a, x);
	}
};

//명시적 바인딩 x
obj.method(2); //1 2

//명시적 바인딩
obj.method.call({a:2}, 3); // 2 3

2. apply 메서드

: call과 완전 똑같지만, this가 아닌 매개변수 값을 괄호로 묶어주는 것만 다르다

let obj = {
	a: 1,
	method: function (x) {
		console.log(this.a, x);
	}
};

//명시적 바인딩
obj.method.call({a:2}, [3]); // 2 3

call / apply 메서드 활용

: 이런 call 과 apply는 어디서 사용되냐면, 유사배열에서 사용이 된다.

/** 유사배열 */
var obj = {
	0: 'a',
	1: 'b',
	2: 'c',
	lenght: 3
};

실제 배열은 아니지만 배열의 형태를 가지고 있다.

인덱스, 0,1,2와 그 안에 데이터와 길이를 가지고 있다.

  • 유사배열의 조건 : 반드시 length가 필요, index가 0번부터 1씩 증가.

따라서, 원래라면 배열이 아니기 때문에

메소드인 slice, push, splice, shift 와 같은 기능을 사용하지 못한다.

하지만, call과 apply가 즉시 실행 함수이기 때문에 this 바인딩 자리에 유사 배열 객체를 넣어주게 된다.

→ 하지만, 원래의 용도로 쓰이는게 아니기 때문에

ES6가 나오면서 Array.from 메서드로 간편하게 객체를 배열로 바꿔주는 메소드가 나오게 되었다.

3. bind

: call이랑 apply랑은 다르게 즉시 호출을 하지 않음

해당 하는 함수를 바인딩해서 새로운 함수를 반환한다.,

  • 목적
    1. 함수에 this를 ‘미리’ 적용
    2. 부분 적용 함수
var func = function (a,b) {
	console.log(this, a, b);
};

func(1, 2); // window 1 2

//this를 미리 적용
var bindFunc1 = func.bind({x: 1});
bindFunc1(5, 6); //{x: 1} 5 6

//부분 적용
var bindFunc2 = func.bind({x: 1}, 4);
bindFunc2(5); //{x: 1} 4 5

name 프로퍼티는 bound라는 접두어가 붙어있다.

bound : bind의 수동태 > 바인드 되었다!라는 뜻

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

  1. 내부함수

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

    이렇게 call을 사용하는 방법도 있지만 bind를 사용하는 방법도 있다.

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

    this를 바인딩 하는 과정이 없기 때문에 scope 체인 상 가장 가까운 this에 접근하게 된다.

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

    느낀점

    오늘은 3주차 강의 내용을 다 들었다..
    this에 대해서 개념이 잘 잡히지 않았고 항상 헷갈렸기 때문에 이 기회에 공부를 제대로 하려고 마음 먹었는데 오늘 배운 내용이 생각보다 복잡하고 이해하기가 어려웠다. call이랑 apply를 어떻게 쓰는지 까지는 알겠는데 왜.. 어떤 상황에서 쓰는지 응용하는 과정에서 코드를 이해하기 어려웠다. 토할것같다 ㅎㅎ
    내일 다시 복습을 해서 개념을 잘 이해하도록 해야겠다.


    오늘은 깃헙 레파지토리를 파서 초기세팅을 해서 push했다. 일단 와이어 프레임을 만들었는데 이 개인 프로젝트는 따로 시리즈를 파서 정리를 해야겠다.

profile
개발 일기장

0개의 댓글