본문 바로가기
내일배움캠프 TIL

2023-10-14~15 주말 TIL

by KMS_99 2023. 10. 16.

2023-10-14~15  주말 TIL

 

내일배움캠프 : JavaScript 문법 종합반 3주차

3주차 10강 : this 바인딩

 

this는 실행컨텍스트의 구성 중 하나로 실행컨텍스트가 생성될 때 생성된다.


전역 환경에서의 this 

1. 노드 환경 => global객체
2. 브라우저 환경 => window 객체

함수 vs 메서드

함수 : 스스로 실행(수행)이 가능 / 함수명();
메서드 : 실행의 주체(객체)가 있어야 실행(수행) 가능 / Object.메서드명();

함수의 this

함수의 this는 전역객체를 가리킨다.
호출의 주체가 없기 때문이다.
함수로서 독립적으로 호출할 때는 this는 항상 전역객체를 가리킨다

메서드의 this
메서드의 this는 호출 주체(객체)를 가리킨다.


3주차 11강 : this 우회방법과 콜백함수, 생성자 함수의 this

 

1. this 우회방법


1-1. 객체 내부의 메서드 내부에서 지정된 함수가 this를 사용하기 위해서 this를 식별자에 할당한다.

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

obj.outer();

 

1-2. 화살표 함수(=this를 바인딩하지 않는 함수)

ES6에서는 함수 내부에서 this가 전역객체를 바라보는 문제 때문에 화살표함수를 도입했다.
ES6에서 처음 도입된 화살표 함수는, 실행 컨텍스트를 생성할 때 this 바인딩 과정 자체가 없다.
따라서 this는 이전의 this값(상위값)이 유지된다. 

결론적으로 일반함수와 화살표함수의 가장 큰차이는 this binding 여부이다.

var obj1 = {
    outer :function () {
        console.log('in outer =>', this); // outer
        var innerFunc = () => {
            console.log('in outer>innerFunc => ', this); // outer 
        };
        innerFunc();
    }
}

obj1.outer();

 

 

2. 콜백함수의 this 바인딩

콜백함수도 기본적으로 함수이기 때문에 전역객체를 바인딩한다.
setTimeout 함수, forEach 메서드는 콜백함수를 호출할 때 콜백함수는 함수이기 때문에 전역객체(window, global)를 바인딩.
단, addEventListener 메서드는 콜백함수 호출시 자신의 this를 상속 (addEventListener의 앞부분)

// 별도 지정 없음 : 전역객체
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.getElementById('a').addEventListener('click',function(e){
    console.log(this,e);
});

 

3. 생성자 함수의 this 바인딩

생성자 함수로 만드는 인스턴스를 지칭

// 생성자 함수
var Cat = function(name, age){
    this.name = name;
    this.age = age;
    this.bark = '야옹';

    console.log(name, '의 this => ', this);
}

var choco = new Cat('초코',7) // this : choco
var nabi = new Cat('나비',5) // this : nabi

3주차 12, 13강 : 명시적 this 바인딩 및 유사배열객체

 

4. 명시적 this binding

 

4-1. call 메서드
함수명.call(바인딩할 객체, ...매개변수)

4-2. apply 메서드
함수명.apply(바인딩할 객체, [매개변수])

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

obj.method(2, 3); // 1, 2, 3
// 즉시실행 메서드 call, apply의 첫 인자에 this를 바인딩 할 객체를 지정할 수 있다.
obj.method.call({a: 4}, 2, 3); // 4, 2, 3
obj.method.apply({a: 4}, [2, 3]); // 4, 2, 3

 

5. call/apply 메서드의 활용 

유사배열객체에 배열메서드를 활용

 

유사 배열의 조건

1. 반드시 length가 필요 (필수)

2. index 번호가 0부터 1씩증가해야한다. (필수x)

// 유사배열객체 
// 1. length 프로퍼티가 있다.
// 2. index 번호가 순서대로 증가.

var obj = {
    0 : 'b',
    1 : 'a',
    2 : 'c',
    length : 3,
};

// 유사배열객체는 바로 배열의 메서드를 활용할 수 없기 때문에 call을통해 배열처럼 활용가능
Array.prototype.push.call(obj,'d');
console.log(obj);

// ES6 신문법, 유사배열객체를 배열로 (권장)
var arr = Array.from(obj);
console.log(arr);

 

6. call과 apply의 활용

객체의 성격(프로퍼티)가 비슷할 경우 공통된 프로퍼티를 묶어 코드의 재사용성을 높힐 수 있다.

// AS-IS (변경 전)
function Student (name, gender, school) {
    this.name = name;
    this.gender = gender;
    this.school = school;
}

function Employee (name, gender, company) {
    this.name = name;
    this.gender = gender;
    this.company = company;
}

var kd = new Student('길동', 'male', '서울대');
var ks = new Employee('길순', 'female', '삼성');
/ TO-BE (변경 후)
function Person(name, gender) {
  this.name = name;
  this.gender = gender;
}

function Student (name, gender, school) {
    Person.call(this, name, gender); // Person 생성자함수에는 Student 인스턴스가 this 바인딩된다.
    this.school = school;
}

function Employee (name, gender, company) {
    Person.apply(this, [name, gender]); // Person 생성자함수에는 Employee 인스턴스가 this 바인딩된다.
    this.company = company;
}

var kd = new Student('길동', 'male', '서울대');
var ks = new Employee('길순', 'female', '삼성');

console.log(kd);
console.log(ks);

 

7. bind 메서드 : this를 바인딩하는 메서드

즉시 호출 메서드인 call, bind와는 다름 (즉시호출 x)

1. 함수에 this를 미리 적용
2. 부분적용함수

var func = function (a,b,c,d) {
    console.log(this, a, b, c, d); // this => 전역객체(global)
}
func(1,2,3,4); // global, 1, 2, 3, 4

// 함수에 this를 미리적용
var bindFunc1 = func.bind({x:1});
bindFunc1(5,6,7,8); // {x:1}, 1, 2, 3, 4

// -----------------------------
// 부분 적용 함수
// name 프로퍼티
// 'bound' 라는 접두어
var bindFunc2 = func.bind({x:1}, 4, 5);  
bindFunc2(6,7);// {x:1}, 4, 5, 6, 7
bindFunc2(10,11); // {x:1}, 4, 5, 10, 11

// binding 된 함수는 추적이 쉬움
console.log(func.name); // func
console.log(bindFunc1.name); // bound func
console.log(bindFunc2.name); // bound func

개인 토이프로젝트 : 계산기

github : https://github.com/kms99/ToyProject-calculator

 

GitHub - kms99/ToyProject-calculator

Contribute to kms99/ToyProject-calculator development by creating an account on GitHub.

github.com

demo : https://kms99.github.io/ToyProject-calculator/

 

Calculator

calc-area 0 ⬅ back clear 0 1 2 3 4 5 6 7 8 9 . / x + - =

kms99.github.io

 

1. UI

display : grid를 사용한 계산기 자판 패턴 구현

 

2. 기능

- 연산자 ( / X + - ) 입력시 누적 계산 실시

- 피연산자 하나당 소수점을 만들 수 있는 (.) 한번씩만 사용가능

- 0 무한입력 예외처리

- 입력 값 지우기 기능 구현

- clear 기능 구현