
(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"