자바스크립트에서 this는 실행 컨텍스트가 생성될 때 바인딩됩니다.
즉, 함수가 호출될 때 this가 결정된다는 것입니다.
아래 소스를 보면 어떻게 호출했느냐에 따라 this가 달라집니다.
var student = {
name: "jennie",
myName: function () {
console.log(this.name);
},
};
var myName = student.myName;
myName(); // undefined
student.myName(); // jennie
결과가 다른 이유는 myName()
은 함수로 호출을 했고 student.myName()
는 메소드로 호출했기 때문입니다.
window.a
는 같고, foo();와 window.foo();
와 같습니다.var a = "Hello?";
function foo() {
console.log("world");
}
console.log(a); // Hello?
console.log(window.a); // Hello?
foo(); // world
window.foo(); // world
아래 소스와 같이 일반 함수로 호출 시 this는 전역 객체를 가리킵니다.(브라우저에서는 window, 노드에서는 global)
function foo() {
function a() {
console.log(this); // window
}
a(); // 일반 함수 호출
}
foo();
var obj = {
foo: function () {
function f() {
console.log(this); //window
}
f(); // 일반 함수 호출
},
};
obj.foo();
오류를 보안해 주기 위해 엄격한 코드 실행을 해주는 환경
"use strict";
var a = "hello";
function foo() {
console.log(this.a); // this === undefined
}
foo();
use strict
모드가 적용되면 this === undefined
로 설정됩니다."use strict";
var a = "hello";
function foo() {
console.log(window.a); // hello
}
foo();
var a = "hello";
var obj = {
a: "world",
foo: function foo() {
console.log(this.a); // world
},
};
obj.foo(); // this는 obj를 가리킵니다.
var a = {
name: "a",
b: {
name: "b",
foo: function () {
console.log(this.name); // b
},
},
};
a.b.foo(); // this는 a.b를 가리킵니다.
var name = "lisa";
var obj = {
name: "jennie",
getName: function () {
console.log(this.name); // jennie (this === obj)
function getThisName() {
console.log(this.name); // lisa (this === window)
}
getThisName();
},
};
obj.getName();
위 소스에서 getThisName
의 this를 obj를 가리키도록(this === obj
) 하려면 어떻게 해야 할까?
this
를 담아 obj를 가리킬 수 있습니다.var name = "lisa";
var obj = {
name: "jennie",
getName: function () {
const newThis = this;
function getThisName() {
console.log(newThis.name); // jennie
}
getThisName();
},
};
obj.getName();
obj
를 가리킵니다.var name = "lisa";
var obj = {
name: "jennie",
getName: function () {
console.log(this.name); // jennie
const getThisName = () => {
console.log(this.name); // jennie
};
getThisName();
},
};
obj.getName();
func.call(thisArg[, arg1[, arg2[, ...]]])
var callback = function () {
console.log(this); // window
};
var obj = {
foo: function (cb) {
cb();
},
};
obj.foo(callback);
this
를 obj
를 가리키려고 한다면 아래와 같이 call
을 사용하여 this를 명시적으로 지정할 수 있습니다.
var callback = function () {
console.log(this); // obj
};
var obj = {
foo: function (cb) {
cb.call(this);
},
};
obj.foo(callback);
call의 경우 arg 인자의 수가 정해져 있지 않습니다.
var string = "hello";
function foo(a, b, c, d, e) {
console.log(this.str);
console.log(arguments);
}
var obj = {
str: "world",
};
foo.call(obj, 1, 2, 3, 4, 5);
func.apply(thisArg, [argsArray])
var string = "hello";
function foo(a, b, c, d, e) {
console.log(this.str);
console.log(arguments);
}
const obj = {
str: "world",
};
foo.apply(obj, [1, 2, 3, 4, 5]);
this값을 설정해 놓은 함수를 실행하지 않고 함수 자체를 반환해줍니다.
func.bind(thisArg[, arg1[, arg2[, ...]]])
var callback = function () {
console.log(this); // obj
};
var obj = {
foo: function (cb) {
cb.call(this);
},
};
setTimeout(callback, 1000);
위와 같이 setTimeout
에 콜백을 담아 넘기면 this는 전역 객체를 가리킵니다.
this
를 obj
를 가리키려고 한다면 아래와 같이 bind
를 사용하여 this를 명시적으로 지정할 수 있습니다.
var callback = function () {
console.log(this); // obj
};
var obj = {
foo: function (cb) {
cb.call(this);
},
};
setTimeout(callback.bind(obj), 1000);
new 연산자를 썼을 때 생성자 함수의 내용을 바탕으로 인스턴트 객체를 만드는 명령으로 새로 만들 인스턴스 객체 자체가 this가 됩니다.
function Foo() {
console.log(this); // {}
}
new Foo(); // 객체 instance
new
키워드를 사용하여 함수를 호출하면 함수 안의 this의 값은 빈 객체
가 할당되어서 함수가 실행됩니다.
function Foo() {
this.name = "sara";
}
var a = new Foo();
위 소스는 아래와 같이 this를 return 해주는 것과 같습니다.
function Foo() {
this.name = "sara";
/*
{
name: 'sara';
}
return this;
*/
}
var a = new Foo();
var name = "sara";
var age = 30;
function Person(name, age) {
this.name = name;
this.age = age;
}
var lisa = Person("lisa", 20);
console.log(window.name, window.age); // lisa, 20
위 소스처럼 new 연산자를 사용하지 않고 호출하게 되면 this는 전역 객체를 가리키게 되고 전역 객체의 name, age의 값은 재할당 하게 됩니다.
var name = "sara";
var age = 30;
function Person(name, age) {
this.name = name;
this.age = age;
}
var lisa = new Person("lisa", 20);
console.log(window.name, window.age); // sara, 30
console.log(lisa);
new 연산자를 사용할 경우 객체가 새로 만들어지면서 그 객체 안에 name, age 프로퍼티가 생성되면서 lisa라는 변수에 담기게 됩니다.