(Node.JS 서버 환경에서의) this 키워드에 대해 알아보자
// nodeJS 서버 환경에선 global 객체를 바인딩
console.log(this === global); // true
// 웹 브라우저에서는 window 객체를 바인딩
console.log(this === window); // true
이렇듯 전역 컨텍스트에서의 this는 전역 객체 global을 참조한다.
function someFunc() {
return this
}
someFunc() === global || window; // true
함수 안에서의 비엄격 모드 Sloppy mode
에서도 this는 전역 객체 global을 참조한다.
Strict mode
를 사용하면 this는 전역 객체를 참조하지 않으며, 엄격 모드 내 정의되지 않은 this는 undefined
가 된다.var player = {
name: "amoeba",
introduce: function () {
return this.name;
}
}
player.introduce(); // amoeba
메소드 안에서 this 키워드가 사용되면 this는 메소드 프로퍼티가 있는 객체를 참조한다.
function hello() {
return this.name;
}
var player = {
name: "amoeba",
introduce: hello
}
player.introduce(); // amoeba
이렇게 this가 특정 함수 안에 위치하고 그 함수가 어떤 객체의 메소드로 활용되면, this는 player라는 지역 객체를 참조한다.
전역 객체가 아닌 이유는 동작되는 시점인 런타임(Runtime) 시점에 맞춰 this가 결정되기 때문이다!
call()
, apply()
, bind()
메소드this
가 참조할 대상 객체를 다른 문맥으로 넘기려면 call
이나 apply
메소드를 활용할 수 있다.
Return Value
: call 메소드는 this 값과 각각 전달된 인수와 함께 함수를 호출한다.
이미 할당되어있는 다른 객체의 함수/메소드를 호출하는 해당 객체에 재할당할 때 사용됩니다. this는 현재 객체(호출하는 객체)를 참조합니다. 메소드를 한번 작성하면 새 객체를 위한 메소드를 재작성할 필요 없이 call()을 이용해 다른 객체에 상속할 수 있습니다.
by MDN
➡️ 즉, 함수에 call 메소드와 그 안에 인자를 활용해 this를 재할당할 수 있다.
function howToStart(name, location) {
this.name = name;
this.location = location;
}
function bootcamp(name, location) {
howToStart.call(this, name, location);
this.merit = "community";
}
var nomad = new howToStart("nico", "Online");
var wecode = new bootcamp("Wecode37th", "Seolleung");
생성자 함수로 객체를 생성할 때 체이닝에도 사용 가능하다.
위 예시에서 call 메소드를 활용해 첫 번째 인자에 this를 넣어 howToStart 함수에 바인딩 시킨 후 이후 인자에 기존 함수의 인자를 받아 생성자 연결에 활용할 수 있다.
var language = "Korean";
var platform = "velog";
function coding() {
var introduce = [
this.language,
'is my first language and',
this.platform,
'is my first platform.'
].join(' ');
console.log(introduce)
var obj = {
language: 'JavaScript',
platform: 'Node.JS'
};
coding.call(obj); // JavaScript is my first language and Node.JS is my first platform.
coding.call(); // Korean is my first language and velog is my first platform.
coding(); // Korean is my first language and velog is my first platform.
대신 call 메소드에 인자를 전달하지 않으면 this는 전역 객체에 바인딩돼 전역 변수를 참조한다.
apply 메소드는 call 메소드와 거의 유사하지만, 두 번째 이후 인자로 배열 혹은 유사 배열 객체를 받는다.
그리고 첫 번째 인자로 비엄격 모드에서의 this, 즉 null이나 undefined를 받는다.
이미 존재하는 함수를 호출할 때 다른 this 객체를 할당할 수 있습니다. this 는 현재 객체, 호출하는 객체를 참조합니다. apply 를 사용해, 새로운 객체마다 메소드를 재작성할 필요없이 한 번만 작성해 다른 객체에 상속시킬 수 있습니다.
by MDN
var stringArray = ['a', 'b,'];
var numberArray = [0, 1, 2];
stringArray.push.apply(stringArray, numberArray);
console.log(stringArray) // ['a', 'b', 0, 1, 2];
이런 식으로 별다른 for문과 같은 함수들 없이 배열의 각 인덱스를 하나로 합칠 수 있다.
concat 메소드와 달리 새로운 배열을 만들지 않는다.
인자로 받는 함수에 this를 바인딩시키는 메소드이다.
this.way = "Offline";
var nomad = {
way = "Online",
howToStudy = function() { return this.way; }
};
nomad.howToStudy(); // "Online"
var wecode = module.howToStudy;
wecode(); // "Offline" - 함수가 전역 스코프에서 호출돼 전역 객체를 참조하기 때문!
var afterWecode = wecode.bind(nomad);
// bind 메소드를 활용해 인자로 받은 객체로 this를 바인딩 시킬 수 있음!
afterWecode(); // "Online"