
자바스크립트에서 this키워드는 항상 함수 내부에서 사용된다. this값은 this가 사용된 함수가 어떤 방식으로 실행 되었는지에 따라 결정된다.
var name = "킹스맨";
var hth = {
name: "하태현",
logName: function () {
console.log(this.name);
}
};
var func = hth.logName;
hth.logName(); // "하태현"
func(); // "킹스맨"
함수 선언시에는 this값을 판별할 수 없다.
this값을 알기 위해선 함수 실행문을 찾고, 어떻게 실행되었는지만 알면 this값을 판별할 수 없다.
위 4가지 실행방법에 따라 this값이 판별된다.
this는 함수가 "어떻게" 실행되느냐에 따라 결정되기 때문에 함수 실행 방식이 중요하다.
var name = "킹스맨"; function log () { console.log(this.name); } func(); // "킹스맨"
func()와 같이 함수이름 만으로 실행하는 경우 일반함수 호출이라고 한다.
일반 함수 호출 방식에서 this값은 Global Object(브라우저에선 window 객체)
var name = "킹스맨"; var hth = { name: "하태현", logName: function () { console.log(this.name); } }; var func = hth.logName; func(); // "킹스맨"
this가 사용된 함수는hth라는 객체의logName이라는 속성으로 할당되어있다.
그러나 함수의 선언이나 할당은this값과 무관하다.
위 예제 코드에서는 함수 실행 부분이func()로 일반 함수 호출 방식으로 실행되었기 때문에this값은 Global Object이다.
var name = "킹스맨"; function foo () { var name = "하태현"; bar(); } function bar () { console.log(this.name); } foo(); // "킹스맨"
bar함수에서this가 사용되었고bar는foo함수 내부에서 일반 함수 호출 방식으로 실행되어서 이때this값은 Global Object이다.
var name = "킹스맨"; var hth = { name: "하태현", printName: function () { foo(); } }; function foo () { console.log(this.name); } hth.printName(); // "킹스맨"
printName은 Dot Notation을 이용해 실행되었지만this가 사용된foo는 일반 함수 호출 방식으로 실행되어this는 Global Object이다.
var name = "킹스맨"; var hth = { name: "하태현", logName: function () { console.log(this.name); } }; var func = hth.logName; // Dot Notation hth.logName(); // Regulat Function Call func();여기서
hth.logName()와func()는 같은 함수를 실행한다. 그러나 실행방식의 차이로this값이 달라진다.
Dot Notation을 이용해 함수를 실행하면, 해당함수 내부의this는 Dot 앞의 객체를 가리킨다.hth.logName()에서this는hth객체를 가리킨다.
var age = 20; function logAge () { console.log(this.age); } var hth = { age: 28, logAge: logAge }; var htg = { age: 26, logAge: hth.logAge }; hth.logAge(); // 28 htg.logAge(); // 26 console.log(hth.logAge); console.log(htg.logAge);
console.log의 결과를 보면 둘다 같은 함수를 가리킨다. 결국hth.logAge(),htg.logAge()를 실행하면this값은 Dot앞의 객체인hth와htg를 가리키게 되어 결과 값이 28, 26이 나온다.
function makePerson(name, age) { return { name: name, age: age, verifyAge: () => { return this.age > 21; } }; } const hth = makePerson("hth", 28); if(hth.verifyAge()){ console.log("Yes Beer"); } else { console.log("No Beer"); }결과는 "No Beer"가 나온다.
예상대로라면 28살이기 때문에 "Yes Beer"가 나와야 하는데...
verifyAge를 자세히 보면 화살표 함수가 쓰였다.
찾아보니 일반함수의 this값은 동적으로 결정 되는데, 화살표 함수는 항상 상위 스코프의 this값을 가리키게 되어있다고 한다.
그래서hth.verifyAge()를 실행하면hth객체의 상위 스코프인 Global Object가this값으로 결정되어this.age는undefined가 된다.
우선 자바스크립트의 객체(배열, 함수)는 내장된 메소드를 가지고 있다. 여기서 설명할 함수 실행 방식은 함수(function)가 갖고 있는 특정 메소드를 이용한 방법이다.
Call, Apply, Bind는 명시적 바인딩을 할때 사용하는 함수이다.
어떤 함수안에서 사용되는 this의 값이 어떤 값이 사용되야하는지 명확할때 사용하는 방식
Function.prototyope.call모든 함수는
.call메소드를 사용할수 있다.function logName () { console.log(this.name); } const person = { name: "하태현", }; // call 메소드를 이용한 함수 실행 logName.call(person); // "하태현"
call메소드의 역할은logName함수의this값을person으로 설정한다.logName함수를 실행(logName()으로 실행하는 것과 같은 의미)function foo (a, b, c) { console.log(this.age + a + b + c); } const hth = { age: 28, }; foo.call(hth, 1, 2, 3); // 34
.call메소드의 첫번째 인자는this값으로 사용되고, 두번째 인자부터 해당함수의 인자로 사용된다.
.call메소드는 받을 수 있는 인자 개수는 제한이 없다.
Function.prototyope.applyfunction foo (a, b, c) { console.log(this.age, a + b + c); } const hth = { age: 28, }; foo.apply(hth, [1, 2, 3]); // 34
.call메소드와 다른게 뭘까??
.apply메소드는 2개의 인자만을 받는다.
첫번째 인자는this값으로 사용되고, 두번째 인자는 무조건 배열 이여야 하고 그 배열의 요소들이 함수의 인자로 전달된다.
.call과 .apply공통점
this값으로 설정차이점
call : 첫번째 인자를 제외한 나머지를 모두 .call이 사용된 함수의 인자로 전달(인자 개수 제한 없음)apply : 두번째 인자로 배열을 받을수 있고, 해당 배열의 모든 요소들을 함수의 인자로 전달(2개의 인자만 받는다)
Function.prototyope.bindfunction foo () { console.log("hello"); } // bar 변수에는 새로운 함수가 담긴다. const bar = foo.bind(); bar();
.bind메소드는 함수를 실행하지 않고 새로운 함수를 반환한다.function logName () { console.log(this.name); } const person = { name: "하태현", }; const bar = foo.bind(hth); bar(); // "하태현"
bar는this값을hth로 설정한foo함수이다.function foo (a, b, c) { console.log(this.age + a + b + c); } const hth = { age: 28, }; const bar = foo.bind(hth, 1, 2, 3); bar(); // 34
bind메소드는call메소드와 유사하게 인자 개수에 제한이 없고, 위 예제 코드에서는this값과 인자값을 저장한 새로운 함수를 만든다.
bind메소드는 새로운 함수를 반환하고, 그 함수를 실행해야 원본 함수가 실행된다.
Keyword(키워드)는 자바스크립트에 내장된 명령어이다.
function foo () { console.log("function"); } new foo();기본적으로
new키워드와 함께 함수를 실행하면 일반 함수 실행문과 동일한 작동을 한다.
function foo () { console.log(this); } new foo(); // 빈 객체 출력function Person (name) { this.name = name; console.log(this); } new Person("hth");필요한 경우 새로운 속성을 추가 할수 있다.
new키워드와 함께 사용될 경우 해당 함수를 생성자 함수라고 부른다.
function Person (name) { this.name = name; console.log(this); } Person("hth"); // 일반함수로 사용 new Person("hth"); // 생성자 함수로 사용보통 일반 함수 용도로 만든 함수는 일반함수로만 사용하고, 생성자함수 용도로 만든 함수는 생성자 함수로만 사용한다.
function Person (name, age) { this.name = name; this.age = age; } new Person("hth", 28);생성자 함수는 통상적으로 함수명을 대문자로 시작한다.