[js] call 함수의 this

merci·2023년 10월 17일
0

JavaScript

목록 보기
15/15

Function.prototype.call()

call() 함수는 첫번째 매개변수를 호출한 함수의 this로 설정합니다.

function greet() {
    console.log("Hello, " + this.name);
}

let person1 = { name: 'John' };
let person2 = { name: 'Jane' };

// 'this'를 person1 객체로 설정
greet.call(person1);  // 출력: Hello, John
greet(person1);       // 출력: Hello, 

// 'this'를 person2 객체로 설정
greet.call(person2);  // 출력: Hello, Jane

.call로 호출한 첫번째 매개변수 person 오브젝트를 greet함수의 this로 사용하고 있습니다.

function Product(name, price) {
  this.name = name;
  this.price = price;
  console.log(this.category);
}

function Food(name, price) {
  this.category = 'food';
  Product.call(this, name, price);  
}

let food = new Food('cheese', 5)  // 출력 : food

console.log(food);

{
    "category": "food",
    "name": "cheese",
    "price": 5
}

위 코드에서 Product생성자 함수를 호출하면서 this를 넣어 주었으므로 Product생성자 함수를 호출하는 FoodthisProduct함수가 사용할 수 있게 됩니다.

.call(null) .call()

아래는 call() 메소드의 첫번째 파라미터가 null인 경우 입니다.

function func(arg1, arg2) {
    console.log(this);  // 전역 객체 (브라우저에서는 window)
    console.log(arg1, arg2);
}

func.call(null, 'hello', 'world');

call() 메소드의 첫번째 파라미터는 호출하려는 함수의 this값을 설정하는데 null을 넣어주게 된다면 호출되는 함수의 this컨텍스트는 전역 객체가 됩니다.
this가 전역 객체가 되므로 .call의 의미가 사라져 사용할 필요가 없습니다.

아래의 2라인은 모두 동일한 코드입니다.

func.call(null, 'hello', 'world');  // 출력 : hello world
func('hello', 'world'); 

아래처럼 첫번째 매개변수를 생략한다면 'hello'func 함수의 this가 됩니다

func.call('hello', 'world');       // 출력 : world undefiled

전역 객체 thissData를 참조

var sData = "Wisen";
function display() {
  console.log("sData value is %s ", this.sData);
}

display.call(); // sData value is Wisen

익명 함수의 call()

즉시 실행함수의 익명함수에서 call() 메소드를 사용하는 예입니다.

var animals = [
  { species: "Lion", name: "King" },
  { species: "Whale", name: "Fail" },
];

for (var i = 0; i < animals.length; i++) {
  (function (i) {
    this.print = function () {
      console.log("#" + i + " " + this.species + ": " + this.name);
    };
    this.print();
  }).call(animals[i], i);
}
// #0 Lion: King
// #1 Whale: Fail

strict mode의 call()

하지만 ECMAScript 5의 엄격 모드(strict mode)에서는 null은 실제로 null 또는 undefined가 됩니다.

'use strict';

function func(arg1, arg2) {
    console.log(this);  // null
    console.log(arg1, arg2);
}

func.call(null, 'hello', 'world');
"use strict";

var sData = "Wisen";

function display() {
  console.log("sData value is %s ", this.sData);
}

display.call(); // Uncaught TypeError : Cannot read the property of 'sData' of undefined


화살표 함수의 this

일반 함수

다음과 같은 버튼이 있을때

<button id="myButton">Click me</button>

이 버튼의 이벤트 리스너의 this는 버튼 태그가 됩니다.

document.getElementById('myButton').addEventListener('click', function(event) {
    console.log(this); 
});

버튼 태그가 아닌 input 태그에 리스너를 추가했다면 this.valueinputvalue가 전달 됩니다.

<input name="textForm" value"" />
document.getElementById('[name="textForm"]').addEventListener('click', function(event) {
    console.log(this.value); 
});

그리고 이벤트 리스너가 호출하는 함수가 아니라면 this는 전역객체를 가리킵니다. ( 엄격 -> undefined)

let obj = {
    value: 'Hello World',
    print: function() {
        function innerFunc() {
            console.log(this.value);
        }
        innerFunc();
    }
};

obj.print(); // undefined 출력

화살표 함수

화살표 함수는 자체적으로 this 바인딩을 생성하지 않고 외부 함수의 this 값을 상속받습니다.
즉, 화살표 함수를 둘러싼 (lexical) 외부 스코프에서의 this 값을 참조합니다.

let obj = {
    value: 'Hello World',
    print: function() {
        let innerFunc = () => {
            console.log(this.value);
        }
        innerFunc();
    }
};

obj.print(); // 'Hello World' 출력
profile
작은것부터

0개의 댓글