Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- 자바스크립트 scope
- 웹 개발 트렌드
- 자바스크립트 상속
- 자바스크립트 연산자
- css3
- 자바스크립트
- 자바스크립트 반복문
- 자바스크립트 클로저
- html 코드
- javascript opreator
- css position
- HTML
- 티스토리챌린지
- 자바스크립트 promise
- CSS
- 프론트엔드
- 자바스크립트 스코프
- javascript opreators
- front-end
- javascript
- 자바스크립트 생성자 함수
- 자바스크립트 실행 컨텍스트
- 자바스크립트 프로미스
- html 주석
- css 포지션
- javascript closure
- 오블완
- css display
- 자바스크립트 async await
- 자바스크립트 클래스
Archives
- Today
- Total
Multi Developer SuHo
자바스크립트 this 키워드, apply, call, bind 함수 본문
SMALL
글을 쓰기 앞서 모든 내용과 소스들은 다음과 같은 강의 플랫폼에서 응용하여 작성하였습니다.
출처: https://inf.run/xNcEg
우선 자바스크립트에서 this 키워드란? -> 현재 실행 컨텍스트(context)를 가리키는 키워드, 다른 말로, this는 현재 작업 중인 객체를 참조하는 의미
자세한 설명은 주석에 구문 하나하나 있습니다.
/**
* this - 자바스크립트에서 this는 현재 실행 컨텍스트(context)를 가리키는 키워드, 다른 말로, this는 현재 작업 중인 객체를 참조하는 의미
*
* JS는 Lexical Scope를 사용하기 때문에 함수의 상위 스코프가
* 정의 시점에 평가된다.
*
* *******하지만 this 키워드는 바인딩이 객체가 생성되는 시점에 결졍된다.
*/
const myFunction = function(){
return this;
}
console.log('-----------------------------------');
console.log(myFunction()); // global Object랑 맵핑이 된거를 볼 수 있다.
console.log('-----------------------------------');
console.log(myFunction() === global); // 실제 this는 global이랑 맵핑이 되는 것을 알 수 있다.
console.log('-----------------------------------');
const winter = {
name: '윈터',
year: 2001,
sayHi: function(){
return `안녕하세요 저는 ${this.name}입니다.`; // 여기서 this.name은 현재 객체를 의미합니다.
},
}
console.log(winter.sayHi()); // this가 현재 (winter)윈터 객체의 매핑이 되는 것을 볼 수 있다.
console.log('-----------------------------------');
function People(name, year){
this.name = name;
this.year = year;
this.sayHi = function(){ // 가장 상위 레벨
return `안녕하세요 저는 ${this.name}입니다.`; // this.name도 실제 객체 맵핑이 된다.
}
}
//만약에 객체를 이 함수로 생성한다고 한다면
const winter2 = new People('윈터', 2001); // winter2는 프로토가 people.prototype이기 때문에 people.prototype에다가 dance() 함수를 추가하면 dance를 실행할 수 있다.
console.log(winter2.sayHi()); // this가 현재 이 winter2 객체에 맵핑되는 것을 볼 수 있다.
// 프로토타입(prototype)에다가 함수를 정의를 해도 this 키워드는 실행하는 대상의 객체로 맵핑이 된다.
People.prototype.dance = function(){ // People의 프로토타입에다 dance라는 함수를 정의
function dance2(){
return `${this.name}가 춤을 춥니다.`;
}
return dance2();
}
console.log('-----------------------------------');
console.log(winter2.dance());
// 객체의 메서드로 가장 상위 레벨에다가 함수를 선언을 하면은 this가 자동으로 실행하는 대상 객체로 맵핑이 된다.
// undefined 값이 나오는 이유 -> 만약 그 외의 위치에다가 함수를 선언을 하게 되면 함수의 this는 무조건 글로벌 오브젝트에 맵핑이 된다.
console.log('-----------------------------------');
/**
* this 키워드가 무엇을 가르키는 세가지만 기억하면 된다.
*
* 1) 일반 함수 호출할땐 this가 최상위 객체 (global 또는 window)를 가리킨다.
* 2) 메서드로 호출할땐 호출된 객체를 가리킨다.
* 3) new 키워드를 사용해서 객체를 생성했을땐 객체를 가리킨다.
* 2번과 3번의 경우가 아닌 경우에는 모두 this가 글로벌 또는 윈도우를 가리킨다고 생각하면 된다.
*/
/**
* 원하는 this 값으로 this를 맵핑하는 방법 세가지
* 1) apply()
* 2) call()
* 3) bind()
*/
function returnName(){ //returnName() 함수 선언
return this.name; // this.name을 반환하는데 this는 글로벌에 맵핑이 된다.
}
console.log(returnName()); // 글로벌로 맵핑이 되기 때문에 글로벌.name은 존재하지 않음 -> undefined가 나옴
console.log('-----------------------------------');
const winter3 = {
name : '윈터',
}
// returnName() this 키워드가 winter3에 맵핑되게 하고 싶을 때
console.log(returnName.call(winter3)); // returnName()을 winter3에 바인딩해서 call하는 의미
// 그래서 this 키워드가 winter3에 바인딩 됐기 때문에 winter3의 name의 value인 "윈터"가 출력된다.
console.log('-----------------------------------');
console.log(returnName.apply(winter3)); // call() 함수와 같은 값을 가져오는 것처럼 보이는데 약간 다르다
console.log('-----------------------------------');
/**
* 1) call -> 콤마를 기반으로 argument(아규먼트)를 순서대로 넘겨주고
* 2) apply -> parametor(매개변수)를 리스트로 입력해야한다.
*/
function testply(x, y, z){
return `${this.name} / 결과값 : ${x * y * z}`;
}
console.log(testply.call(winter3, 5,10,20)); // x, y, z 라는 파라미터(매개변수)를 콤마 기준으로 배분하면 된다.
console.log('-----------------------------------');
console.log(testply.apply(winter3, [5,10,20])); // array로 하나만 받는다.
console.log('-----------------------------------');
/**
* bind()
* this를 바인딩만 해놓고서 나중에 실행할 수 있다.
*/
const finishFunc = testply.bind(winter3, 5, 10, 15); // winter3에다가 바인딩을 한다는 의미
console.log(finishFunc);
console.log('-----------------------------------');
console.log(finishFunc());
console.log('-----------------------------------');
// call, apply, bind 모두 원하는 함수에다가 원하는 객체를 바인딩할 수 있는 방법 -> this 키워드를 지정해줄 수 있다.(어떤 객체가 this의 해당이 될지)
// call 이랑 apply 함수는 실행을 하는 순간에 바로 함수가 실행이 된다.
// call에서는 콤마 기준으로 parametor(매개변수)를 배분하면 된다.
// apply는 Array로 순서대로 parametor(매개변수)를 입력해주면 된다.
// bind 같은 경우에는 바인드(bind)를 한 다음에 바로 함수가 실행되지 않고, 바인드(bind)가 된 함수를 반환을 또 해준다.
// 나중에 바인드만 해놓고 나중에 실행할 수 있는 기능이 bind() 라는 함수다.
myFunction 이라는 함수를 정의하고 this를 반환하는데 여기서 출력된 결과를 보시면 Object [global] 이라는 객체가 보이시나요? -> global Object 랑 맵핑(다른구조나, 다른형식으로 변환이나 연결되는 과정)이 되는 것을 보실 수 있습니다.
const myFunction = function(){
return this;
}
console.log('-----------------------------------');
console.log(myFunction()); // global Object랑 맵핑이 된거를 볼 수 있다.
다음은 비교하는 구문입니다.
console.log(myFunction() === global); // myFunction이란 함수를 호출하고 그 결과값이 전역 객체(global)와 동일한지 비교 -> 실제 this는 global이랑 맵핑이 되는 것을 알 수 있다.
출력되는 값은 true입니다.
이 부분은 같은 값이 나와서 하나로 묶어서 보겠습니다.
두개의 구문에서 다른점을 발견하셨나요? -> sayHi() 함수에 this 키워드 사용과 각 프로퍼티에 대한 this 키워드 사용 입니다.
const winter = {
name: '윈터',
year: 2001,
sayHi: function(){
return `안녕하세요 저는 ${this.name}입니다.`; // 여기서 this.name은 현재 객체를 의미합니다.
},
}
console.log(winter.sayHi()); // this가 현재 (winter)윈터 객체의 매핑이 되는 것을 볼 수 있다.
console.log('-----------------------------------');
function People(name, year){
this.name = name;
this.year = year;
this.sayHi = function(){ // 가장 상위 레벨
return `안녕하세요 저는 ${this.name}입니다.`; // this.name도 실제 객체 맵핑이 된다.
}
}
//만약에 객체를 이 함수로 생성한다고 한다면
const winter2 = new People('윈터', 2001); // winter2는 프로토가 people.prototype이기 때문에 people.prototype에다가 dance() 함수를 추가하면 dance를 실행할 수 있다.
console.log(winter2.sayHi()); // this가 현재 이 winter2 객체에 맵핑되는 것을 볼 수 있다.
여기서 부터는 어려운 내용보다 주석으로 설명한 부분을 참고하시면 되겠습니다!!
//만약에 객체를 이 함수로 생성한다고 한다면
const winter2 = new People('윈터', 2001); // winter2는 프로토가 people.prototype이기 때문에 people.prototype에다가 dance() 함수를 추가하면 dance를 실행할 수 있다.
console.log(winter2.sayHi()); // this가 현재 이 winter2 객체에 맵핑되는 것을 볼 수 있다.
// 프로토타입(prototype)에다가 함수를 정의를 해도 this 키워드는 실행하는 대상의 객체로 맵핑이 된다.
People.prototype.dance = function(){ // People의 프로토타입에다 dance라는 함수를 정의
function dance2(){
return `${this.name}가 춤을 춥니다.`;
}
return dance2();
}
console.log('-----------------------------------');
console.log(winter2.dance());
// 객체의 메서드로 가장 상위 레벨에다가 함수를 선언을 하면은 this가 자동으로 실행하는 대상 객체로 맵핑이 된다.
// undefined 값이 나오는 이유 -> 만약 그 외의 위치에다가 함수를 선언을 하게 되면 함수의 this는 무조건 글로벌 오브젝트에 맵핑이 된다.
console.log('-----------------------------------');
/**
* this 키워드가 무엇을 가르키는 세가지만 기억하면 된다.
*
* 1) 일반 함수 호출할땐 this가 최상위 객체 (global 또는 window)를 가리킨다.
* 2) 메서드로 호출할땐 호출된 객체를 가리킨다.
* 3) new 키워드를 사용해서 객체를 생성했을땐 객체를 가리킨다.
* 2번과 3번의 경우가 아닌 경우에는 모두 this가 글로벌 또는 윈도우를 가리킨다고 생각하면 된다.
*/
/**
* 원하는 this 값으로 this를 맵핑하는 방법 세가지
* 1) apply()
* 2) call()
* 3) bind()
*/
function returnName(){ //returnName() 함수 선언
return this.name; // this.name을 반환하는데 this는 글로벌에 맵핑이 된다.
}
console.log(returnName()); // 글로벌로 맵핑이 되기 때문에 글로벌.name은 존재하지 않음 -> undefined가 나옴
console.log('-----------------------------------');
const winter3 = {
name : '윈터',
}
// returnName() this 키워드가 winter3에 맵핑되게 하고 싶을 때
console.log(returnName.call(winter3)); // returnName()을 winter3에 바인딩해서 call하는 의미
// 그래서 this 키워드가 winter3에 바인딩 됐기 때문에 winter3의 name의 value인 "윈터"가 출력된다.
console.log('-----------------------------------');
console.log(returnName.apply(winter3)); // call() 함수와 같은 값을 가져오는 것처럼 보이는데 약간 다르다
console.log('-----------------------------------');
/**
* 1) call -> 콤마를 기반으로 argument(아규먼트)를 순서대로 넘겨주고
* 2) apply -> parametor(매개변수)를 리스트로 입력해야한다.
*/
function testply(x, y, z){
return `${this.name} / 결과값 : ${x * y * z}`;
}
console.log(testply.call(winter3, 5,10,20)); // x, y, z 라는 파라미터(매개변수)를 콤마 기준으로 배분하면 된다.
console.log('-----------------------------------');
console.log(testply.apply(winter3, [5,10,20])); // array로 하나만 받는다.
console.log('-----------------------------------');
/**
* bind()
* this를 바인딩만 해놓고서 나중에 실행할 수 있다.
*/
const finishFunc = testply.bind(winter3, 5, 10, 15); // winter3에다가 바인딩을 한다는 의미
console.log(finishFunc);
console.log('-----------------------------------');
console.log(finishFunc());
console.log('-----------------------------------');
// call, apply, bind 모두 원하는 함수에다가 원하는 객체를 바인딩할 수 있는 방법 -> this 키워드를 지정해줄 수 있다.(어떤 객체가 this의 해당이 될지)
// call 이랑 apply 함수는 실행을 하는 순간에 바로 함수가 실행이 된다.
// call에서는 콤마 기준으로 parametor(매개변수)를 배분하면 된다.
// apply는 Array로 순서대로 parametor(매개변수)를 입력해주면 된다.
// bind 같은 경우에는 바인드(bind)를 한 다음에 바로 함수가 실행되지 않고, 바인드(bind)가 된 함수를 반환을 또 해준다.
// 나중에 바인드만 해놓고 나중에 실행할 수 있는 기능이 bind() 라는 함수다.
감사합니다. 출력결과가 다른신 분들은 말씀해주시면 되겠습니다! 댓글에 간단한 인사나 하고싶은 말 있으시면 달아주세요!!
LIST
'JavaScript' 카테고리의 다른 글
자바스크립트 Closure(클로저) (0) | 2024.01.19 |
---|---|
자바스크립트 Execution Context (실행 컨텍스트) (0) | 2024.01.11 |
자바스크립트 스코프(Scope), 렉시컬 스코프(Lexical Scope), 다이나믹 스코프(Dynamic Scope) (0) | 2024.01.06 |
자바스크립트 Prototype Chain(프로토타입 체인) (0) | 2024.01.01 |
자바스크립트 Constructor Function(생성자 함수), 전역객체(Global Object) (0) | 2023.12.26 |