자바스크립트 call, apply, bind 함수 비교 및 성능 분석

2024-04-23

자바스크립트에서 call과 apply 함수의 차이점

인수 전달 방식

  • call: 첫 번째 인수로 this 값을 지정하고, 두 번째 인수부터 원하는 인수를 순서대로 쉼표로 구분하여 전달합니다.
function greet(name) {
  console.log(`안녕하세요, ${name}님!`);
}

const person = {
  name: '홍길동',
};

greet.call(person, '수잔'); // 안녕하세요, 수잔님!
  • apply: 첫 번째 인수로 this 값을 지정하고, 두 번째 인수로 배열 또는 arguments 객체를 전달합니다. 배열 또는 arguments 객체에 원하는 인수를 모두 포함시킵니다.
function greet(name) {
  console.log(`안녕하세요, ${name}님!`);
}

const person = {
  name: '홍길동',
};

const args = ['수잔'];
greet.apply(person, args); // 안녕하세요, 수잔님!

성능

일반적으로 call 함수가 apply 함수보다 성능이 우수합니다. 왜냐하면 apply 함수는 인수 배열을 매번 새로 생성해야 하기 때문입니다. 따라서 인수 개수가 많거나 성능이 중요한 상황에서는 call 함수를 사용하는 것이 좋습니다.

사용 시나리오

  • call: 특정 객체의 메서드를 다른 객체의 컨텍스트에서 호출하고 싶을 때 사용합니다.
function greet() {
  console.log(`안녕하세요, ${this.name}님!`);
}

const person1 = {
  name: '홍길동',
};

const person2 = {
  name: '이순신',
};

greet.call(person2); // 안녕하세요, 이순신님!
  • apply: 인수 배열을 직접 전달하고 싶을 때 또는 인수 개수가 불확실할 때 사용합니다.
function sum(a, b) {
  return a + b;
}

const numbers = [10, 20];
const result = sum.apply(null, numbers); // 30

bind 함수와의 비교

bind 함수는 함수를 미리 바인딩하여 새로운 함수를 만드는 데 사용됩니다. callapply 함수와 달리 bind 함수는 함수 호출 시점에 인수를 전달하지 않습니다.

function greet(name) {
  console.log(`안녕하세요, ${name}님!`);
}

const person = {
  name: '홍길동',
};

const greetPerson = greet.bind(person);
greetPerson('수잔'); // 안녕하세요, 수잔님!

결론




예제 코드

예제 1: call 함수 사용

function greet(name) {
  console.log(`안녕하세요, ${name}님!`);
}

const person = {
  name: '홍길동',
};

const anotherPerson = {
  name: '이순신',
};

greet.call(person); // 안녕하세요, 홍길동님!
greet.call(anotherPerson); // 안녕하세요, 이순신님!

설명:

  • greet.call(person): greet 함수를 person 객체의 컨텍스트에서 호출합니다. 따라서 this 키워드는 person 객체를 참조합니다.
function sum(a, b) {
  return a + b;
}

const numbers1 = [10, 20];
const numbers2 = [30, 40];

const result1 = sum.apply(null, numbers1); // 30
const result2 = sum.apply(null, numbers2); // 70
  • sum.apply(null, numbers1): sum 함수를 null 객체의 컨텍스트에서 호출하고, 인수 배열 numbers1을 전달합니다.
function greet(name) {
  console.log(`안녕하세요, ${name}님!`);
}

const person = {
  name: '홍길동',
};

const greetPerson = greet.bind(person);
greetPerson('수잔'); // 안녕하세요, 수잔님!
  • const greetPerson = greet.bind(person): greet 함수를 person 객체에 바인딩하여 새로운 함수 greetPerson을 만듭니다.
  • greetPerson('수잔'): greetPerson 함수를 호출하고, 인수 '수잔'을 전달합니다.

참고:

  • 위 예제 코드는 단순히 call, apply, bind 함수의 기본적인 사용법을 보여주는 데 목적이 있습니다. 실제 개발에서는 상황에 맞게 적절하게 사용해야 합니다.



call, apply, bind 함수 대체 방법

화살표 함수 사용:

function greet(name) {
  console.log(`안녕하세요, ${name}님!`);
}

const person = {
  name: '홍길동',
};

const greetPerson = (name) => console.log(`안녕하세요, ${name}님!`);

greetPerson('수잔'); // 안녕하세요, 수잔님!
  • 위 코드는 화살표 함수를 사용하여 greet 함수와 동일한 기능을 수행합니다. 화살표 함수는 익명 함수의 일종이며, 간결하고 코드 가독성을 높이는 장점이 있습니다.

객체 프로토타입 확장:

function greet(name) {
  console.log(`안녕하세요, ${name}님!`);
}

const person = {
  name: '홍길동',
  greet: greet,
};

person.greet('수잔'); // 안녕하세요, 수잔님!
  • 위 코드는 객체 프로토타입을 확장하여 greet 함수를 person 객체에 직접 추가합니다. 이렇게 하면 call, apply, bind 함수를 사용하지 않고도 객체의 메서드처럼 greet 함수를 호출할 수 있습니다.

함수 컴포지션 라이브러리 사용:

const compose = require('compose'); // 함수 컴포지션 라이브러리 임포트

function greet(name) {
  return `안녕하세요, ${name}님!`;
}

const person = {
  name: '홍길동',
};

const greetPerson = compose(greet, (obj) => obj.name);

console.log(greetPerson(person)); // 안녕하세요, 홍길동님!
  • 위 코드는 compose 함수 컴포지션 라이브러리를 사용하여 greet 함수와 name 프로퍼티를 조합하는 새로운 함수 greetPerson을 만듭니다. 함수 컴포지션 라이브러리를 사용하면 코드를 더욱 모듈화하고 재사용 가능하게 만들 수 있습니다.

프록시 객체 사용:

function greet(name) {
  console.log(`안녕하세요, ${name}님!`);
}

const person = {
  name: '홍길동',
};

const greetPerson = new Proxy(greet, {
  apply: function(target, thisArg, args) {
    return target.apply(thisArg, args.concat('수잔'));
  },
});

console.log(greetPerson(person)); // 안녕하세요, 홍길동님!
console.log(greetPerson()); // 안녕하세요, 수잔님!
  • 위 코드는 프록시 객체를 사용하여 greet 함수의 apply 메서드를 재정의합니다. 이렇게 하면 greetPerson 함수를 호출할 때마다 마지막 인수로 '수잔'을 자동으로 추가할 수 있습니다.

주의:

  • 위에 제시된 대체 방법들은 각각 장단점이 있습니다. 상황에 맞게 적절한 방법을 선택해야 합니다.
  • call, apply, bind 함수는 여전히 유용한 함수이며, 특정 상황에서 더 효율적일 수 있습니다.

javascript function performance


HTML DOM 조작: div 요소 텍스트 변경 완벽 가이드

innerText 속성은 div 요소 내부의 모든 텍스트 노드를 포함하는 문자열을 가져오거나 설정하는 데 사용됩니다. 다음 코드는 innerText 속성을 사용하여 div 요소의 텍스트를 "안녕하세요!"로 변경하는 예시입니다...


jQuery로 이름으로 요소 선택하기: 예제 코드

이름 속성은 HTML 요소를 식별하는 데 사용되는 고유한 속성이며, jQuery를 사용하여 이름으로 요소를 선택하는 데 활용할 수 있습니다.다음은 jQuery로 이름으로 요소를 선택하는 몇 가지 방법입니다:$('[name="요소 이름"]') 사용하기:...


Node.js fs.readFile(): 왜 버퍼를 반환할까요?

| 기준 | | | |---|---|---| | 활동 수준 | 높음 | 중간 | 낮음 | | 훈련 용이성 | 쉬움 | 어려움 | 매우 어려움 | | 사회성 | 다른 개와 사람을 좋아함 | 다른 고양이와 사람을 좋아함 (품종에 따라 다름) | 혼자 있기를 좋아함 |...


Node.js를 사용하여 파일 다운로드하기 (외부 라이브러리 사용 없음)

필수 조건:Node. js 설치다운로드하려는 파일에 대한 URL단계:http 모듈 가져오기:다운로드 요청 만들기:오류 처리:응답 데이터 처리:설명:http 모듈은 HTTP 요청을 만들고 처리하는 데 사용됩니다.http...


Google 드라이브 이미지 표시 문제 해결 (JavaScript, HTML, 이미지)

해결 방법:HTML 코드:YOUR_FILE_ID를 실제 Google 드라이브 파일 ID로 바꿔주세요.export=view 옵션은 이미지를 미리보기 모드로 표시합니다.원하는 경우 width 및 height 속성을 추가하여 이미지 크기를 조정할 수 있습니다...


javascript function performance