JavaScript/3주차

13. call apply bind 응용

tnals634 2023. 5. 24. 22:10

사용하기전 코드를 살펴보자.

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 kd = new Employee('길순', 'female', '삼성');

여길 보면 똑같이 이름과 성별이 겹친다.

 

그래서 이 같은것을 따로 빼려고한다. 그때 call을 사용해서 사람이라는 공동 함수로 빼준다.

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

function Student(name, gender, school) {
    Person.call(this, name, gender);
    this.school = school;
}

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

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

이렇게 효율화를 추구하는 코드가 됬다.

 

 

또다른 방법도 있다.

먼저 아래와 같이 새 예시를 작성해준다.

var numbers = [1, 2, 3, 4, 5];
var max = (min = numbers[0]); // 1

numbers.forEach(function(number) {
    //현재 돌아가는 숫자가 max보다 큰 경우
    if (number > max) {
        max = number;
    }

    //~~
    if(number < min) {
        min = number;
    }
});

console.log(max,min);

 

하지만 위와 같이 작성하기엔 좀 아쉽게도 가독성도 안좋고 코드도 기니까 줄일 수 있는 방법으로 apply를 사용준다.

//apply 활용
var numbers = [1, 2, 3, 4, 5];

//일단 this를 생략하고 apply를 써서 바로 구해줄 수 있다.
var max = Math.max.apply(null, numbers);
var min = Math.min.apply(null, numbers);

console.log(max,min);

 

 

spread operator

//spread operator도 Math.max()를 쓸 수 있다.
//배열의 형태를 풀어줄수 있다.
console.log(...numbers);

이걸 그대로 Math.max와 min에 넣어주면 된다.

var max = Math.max(...numbers);
var min = Math.min(...numbers);

 

 

 

bind

 -> this를 바인딩 하는 메서드

- call , apply와 다르게 즉시 호출하지 않는다.

 - 해당 함수를 this에 바인딩해서 새로운 함수를 return한다. 그 return한 것을 변수가 다시 받아서 그다음에 사용하는 것이다.

//bind 에서도 
// -> this 를 바인딩 하는 메서드
//call, apply와는 좀 다르다. 즉시 호출하지 않는다.
//해당하는 함수를 this 바인딩해서 새로운 함수를 return 한다.
//그 return한 것을 변수가 다시 받아서 그다음에 사용하는것이다.

// 목적
// 1. 함수에 this를 '미리' 적용한다.
// 2. 부분 적용 함수

//1번 예시
var func = function (a, b, c, d) {
    console.log(this, a, b, c, d);
};

func(1, 2, 3, 4); //global 객체

//이런걸 방지하기위해 bind를 하는 거다.

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

미리 숫자를 할당해서 사용할 수도 있다.

// 2번 예시
var bindFunc2 = func.bind({x:1}, 4, 5);
// bindFunc2(6,7);
bindFunc2(10, 11);

 

네임 프로퍼티를 가지고 있는데 이것 덕분에 쉽게 찾아낼 수 있다.

//name 프로퍼티
// 어느 함수든 갖고 있다.
//거기에 'bound'라는 접두어가 붙어있다.
//그래서 추적하기가 매우 쉽다.

console.log(func.name); //func
console.log(bindFunc1.name); // bound func
console.log(bindFunc2.name); // bound func

 

 

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

 - 1. 내부함수

     - 메서드의 내부 함수에서 메서드의 this를 그대로 사용하기 위한 방법

     - 변수를 활용하는 우회법보다 call, apply, bind를 사용하면 깔끔하게 처리 가능

//call을 쓰는 방법
var obj = {
    outer: function () {
        console.log(this); //obj
        var innerFunc = function () {
            console.log(this);
        };

        //call을 이용해서 즉시 실행하면서 this를 넘겨줌
        innerFunc.call(this); //obj
    }
};
obj.outer();
//bind 이용 (이방법을 더 많이 쓰임)
var obj = {
    outer: function () {
        console.log(this);
        var innerFunc = function () {
            console.log(this);
        }.bind(this); //innerFunc에 this를 결합한 새로운 함수를 할당
        innerFunc();
    }
};
obj.outer();

 

 

화살표 함수 예외 사항

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

 - b. 이 함수 내부에는 this의 바인딩과정이 아예없다.

 - c. 우회, call, apply, bind보다 편리한 방법

//화살표 함수 이용
var obj = {
    outer: function () {
        console.log(this);
        var innerFunc = () => {
            console.log(this);
        };
        innerFunc();
    }
};

obj.outer();

 

 

이방법을 알고있는것이 중요