자바스크립트 함수 호출, this

zin·2023년 8월 18일
1

this는 자신을 호출한 객체, 자신이 생성할 객체
이 두 경우 객체를 가리키는 자기 참조변수.

this 는 함수가 만들어질 때가 아닌 '실행'될 때 그 값이 결정된다.
상황별로 호출 방법이 다양하다.

this 함수 호출 방법

1. 일반적인 함수 호출:

일반적인 함수 호출에서 this는 전역 객체인 window(node는 global)를 가리킨다.

function a(){
    console.log(this)
}
a()
//Window {0: Window, 1: global, window: Window, self: Window, document: document, name: '', location: Location, …}
//undefined

전역공간에 선언하는 함수는 전역공간을 가리킨다. 메서드호출이 아닌 a()함수를 직접 호출하여 함수의 컨텍스트가 어디 속하는지 알 수 없기 때문에 undefined를 출력한다.

2. 메서드 호출 :

메서드로 호출한 경우 this는 멤버접근연산자 앞의 객체를 가리킨다.
메서드를 어떻게 호출했냐에 따라 this바인딩이 달라진다.

const obj = {
	val: 100,
	func: function() {
	  console.log(this) //obj객체를 가리킴
	}
}
obj.func()

3. 생성자 함수 호출:

생성자 함수 내에서 this는 새로 생성되는 인스턴스 객체를 가리킨다.

생성자 함수를 사용하면 공통된 속성과 메서드를 가진 객체들을 쉽게 생성하고 관리할 수 있다. 이런 과정은 new키워드와 생성자함수를 호출한 경우에만 실행된다.

function Person(name, age) { 
    this.name = name; //객체를 생성하고 초기화 한다
    this.age = age;
}

// 생성자 함수 호출
const person1 = new Person('Alice', 30); 
const person2 = new Person('Bob', 25);

console.log(person1); // { name: 'Alice', age: 30 }
console.log(person2); // { name: 'Bob', age: 25 }

4. apply(), call(), bind() 사용:

이 세가지 함수를 사용하여 this 값을 수동으로 설정할 수 있다.

  • call(), apply() - 어떤 함수를 다른객체의 메서드처럼 호출할 수 있게 한다. 넘겨받는 인자의 형식만 다를 뿐, this를 특정 객체에 바인딩하여 함수를 호출하는 역할을 한다.
  • bind() - 함수의 this바인딩을 영구적으로 변경한다. 함수가 어디서 어떻게 호출되는지에 상관없이 this의 값을 고정하고 싶을때 사용한다.

call()

첫번째 인자로 this로 바인딩할 객체를 지정한다.
peter객체를 call()의 인자로 넘겨 bruce 객체가 this로 바인딩.
sayName() 함수 내에서 this.name을 통해 bruce 객체의 name 프로퍼티에 접근할 수 있게 된다.

var peter = {
  name : 'Peter Parker',
  sayName : function(){    
		console.log(this.name);
	}
}

var bruce = {
  name : 'Bruce Wayne',
}
peter.sayName.call(bruce);
//Bruce Wayne

apply()

call() 와 동일하지만, 호출하는 함수에 전달할 인자들을 배열형태로 전달해야 한다.

const obj = {name: 'Lee'}
function user(age,country) {
    return `name: ${this.name}, age: ${age}, country: ${country}`
}
console.log(user.apply(obj, [20,'korea']))
//name: Lee, age: 20, country: korea

bind()

bind()는 this 값을 고정시키는 메서드로 함수를 호출할 때 함수 내부에서 this가 어떤 객체를 가리킬지를 명시적으로 지정할 수 있도록 도와준다. 이를 통해 함수를 나중에 호출할 때 this 값이 항상 고정된다.

this 를 바인딩하여 함수를 호출하지않고, 새로운 함수를 반환한다.

const person = {
  firstName: "Zanmang",
  lastName: "loopy",
  getFullName: function() {
    return this.firstName + " " + this.lastName;
  }
};

const printFullName = person.getFullName;
console.log(printFullName()); // 결과: undefined undefined

const boundPrintFullName = printFullName.bind(person);
console.log(boundPrintFullName()); // 결과: Zanmang loopy

bind()를 사용하여 person.getFullName 함수의 this 값을 person 객체로 고정시킨 새로운 함수를 생성하면, 해당 함수를 호출할 때 this가 항상 person 객체를 가리킨다.

5. 화살표 함수:

화살표 함수 내에서 this는 함수를 둘러싼 스코프의 this를 그대로 가져온다.
즉, 화살표 함수 내에서의 this는 함수를 정의할 때의 컨텍스트를 유지한다.

화살표 함수의 경우 상위 스코프의 this를 가리킨다(Lexical this)

// a에서 this = person
// b에서 this = 상위스코프(상위에서 person을 보고있음) 즉 person
// c에서 this = 상위스코프(상위에서 person을 보고있음) 즉 person
const person = {
    name: 'Loopy',
    age: 25,
    a(){
        console.log(this);
        console.log(this.name);
        let b = () => {
            console.log(this);
            console.log(this.name);
            let c = () => {
                console.log(this);
                console.log(this.name);
            }
            c()
        }
        b()
    }
}
person.a()

//출력
{name: 'Loopy', age: 25, a: ƒ} 
Loopy

{name: 'Loopy', age: 25, a: ƒ} 
Loopy

{name: 'Loopy', age: 25, a: ƒ}
Loopy

이런 특징으로 화살표함수의 this는 생성자 함수, call(),apply(),bind()함수를 사용하여 변경할 수 없다. 아래 코드처럼 call()을 사용해도 화살표함수의 this는 변경되지 않고, 전역객체를 가리킨다.

💡 정리

this 를 쓰는 이유?

  • this를 통해 코드를 더 유연하고, 재사용 가능하다.
  • 객체의 메서드 내에서 해당 객체의 속성과 메서드에 접근하기 위해 사용한다.
  • 생성자 함수를 사용하여 새로운 인스턴스 객체를 생성, 초기화한다.
  • 이벤트 핸들러 함수 내에서 이벤트가 발생한 요소와 관련된 작업을 처리한다.
  • 화살표 함수를 사용하여 스코프 내의 this 값을 유지하고 코드를 간결하게 작성한다.
profile
프론트엔드 가보자고-!

1개의 댓글

comment-user-thumbnail
2023년 8월 18일

유익한 글이었습니다.

답글 달기