This
Javascript에서 '나 자신' 이라는 뜻이다.
어떤 상황인지에 따라서 '나 자신'은 계속해서 바뀌고 This가 무엇인지에 따라서 의미(값)도 바뀐다.
var myName = 'window name';
function log() {
console.log(this.myName);
}
var obj = {
myName: 'jasn',
logName: log,
};
log(); // undefined
obj.logName(); // jasn
바닐라코딩 영상을 보면서 this를 정리해봤는데
처음부터 막힌 부분은 vscode에서 node를 이용해서 출력해보니
log(); 를 실행했을 때 'window name'이 아니라 계속 undefined가 나오는 것이었다.
이유를 찾아보니 node와 웹에서 전역 범위에 접근하는 건 서로 다른 구문이 필요하다는 것이다.
웹에서는 window, self, frames 등을 사용할 수 있지만
node.js 에서는 global을 사용해야 한다.
그래서 이 두 글로벌 객체의 명칭을 globalThis로 통일했다고 한다.
위 구문을 이용 하려면 크롬에서는 window, globalThis를 이용해야 하고
node에서는 global과 globalThis 를 이용해야한다.
아직까지 양쪽에서 window, global을 각각 지원하는 이유는 호환성 때문에 없애지 못한 것이다.
globalThis.myName = 'window name';
function log() {
console.log(this.myName);
}
var obj = {
myName: 'jasn',
logName: log,
};
log(); // window name
obj.logName(); // jasn
node에서 다시 출력이 잘 되는 걸 확인할 수 있다.
일반 함수 실행 방식에서 this
stric mode가 아닐 때 foo(); 와 같이 일반 함수 실행 방식으로 this를 출력해보면
this는 global객체(브라우저에서는 윈도우)를 가르킨다.
function foo() {
console.log(this); // 'this' === global object (브라우저상에서는 window 객체)
}
foo();
// ========================= 출력값 ==============================
/*
<ref *1> Object [global] {
global: [Circular *1],
clearInterval: [Function: clearInterval],
clearTimeout: [Function: clearTimeout],
setInterval: [Function: setInterval],
setTimeout: [Function: setTimeout] {
[Symbol(nodejs.util.promisify.custom)]: [Function (anonymous)]
},
queueMicrotask: [Function: queueMicrotask],
clearImmediate: [Function: clearImmediate],
setImmediate: [Function: setImmediate] {
[Symbol(nodejs.util.promisify.custom)]: [Function (anonymous)]
}
}
*/
strict mode에서는 undefined이 출력되는 걸 확인할 수 있다.
'use strict';
function foo() {
console.log(this); // stric mode에서 this는 undefined
}
foo(); // undefined
함수에서 일반 함수 실행 방식으로 this를 불러도 this는 global(window) 객체가 된다.
globalThis.age = 100;
function foo() {
let age = 99;
bar();
}
function bar() {
console.log(this.age); // 100
// 'use strict' 을 쓰면 age가 정의되지 않았다고 error가 뜬다.
}
foo();
Dot Notation(점 방식)에서 this
Dot Notation(점 방식)에서 this는 점 앞에 있는 객체를 나타낸다.
globalThis.age = 100;
let jasn = {
age: 31,
foo: function bar() {
console.log(this.age);
},
};
let ken = {
age: 35,
foo: jasn.foo,
};
let foo = jasn.foo;
jasn.foo(); // 31 (점으로 불렀을 때 this는 점 앞의 객체)
ken.foo(); // 35 (점으로 불렀을 때 this는 점 앞의 객체)
foo(); // 100 (일반함수 방식일 때 this는 윈도우)
Function.prototype.call, Function.prototype.bind, Function.prototype.apply
위 3가지는 this값을 직접적으로 지정해주는 방식으로
이 때 this는 function의 인자 값(지정한 객체) 가 된다.
globalThis.age = 100;
function foo() {
console.log(this.age);
}
let ken = {
age: 35,
};
let jasn = {
age: 31,
};
foo(); // 100
foo.call(ken); // 35
foo.apply(jasn); // 31
인자가 여러개인 경우에는 첫 번째 인자가 되는 객체가 this가 되고
나머지는 arguments가 된다.
globalThis.age = 100;
function foo(a, b, c, d, e) {
console.log(this.age);
console.log(arguments);
}
let jasn = {
age: 31,
};
// call은 인자의 수가 정해져 있지 않다.
// 첫 번째 인자 : this , 나머지 : arguments
foo.call(jasn, 1, 2, 3, 4, 5); // 31 , [Arguments] { '0': 1, '1': 2, '2': 3, '3': 4, '4': 5 }
// apply는 인자를 두 개만 받는다.
// 첫 번째 인자 : this , 두 번째 인자 : 무조건 배열(배열의 요소들이 arguments)
foo.apply(jasn, [1, 2, 3, 4, 5]); // 31, [Arguments] { '0': 1, '1': 2, '2': 3, '3': 4, '4': 5 }
bind는 바로 함수를 실행하지 않고 인자로 받은 객체를 this로 설정하고 함수를 반환한다.
일반 함수실행 방식으로 해당 함수를 실행 해보면 인자로 받은 객체가 this가 된 것을 확인할 수 있다.
globalThis.age = 100;
function foo() {
console.log(this.age);
console.log(arguments);
}
let jasn = {
age: 31,
};
// bind는 바로 함수를 실행하지 않는다. 인자로 받은 객체를 this로 설정하고 함수를 반환
// 첫 번째 인자 : this
let bar = foo.bind(jasn);
// 함수를 실행
bar(1, 2, 3, 4, 5); // 31, [Arguments] { '0': 1, '1': 2, '2': 3, '3': 4, '4': 5 }
'new' 키워드에서 this
new를 사용하여 함수를 호출할 때 this를 찍어보면
새로 생성되서 할당 된 새로운 객체가 찍히는 걸 확인할 수 있다.
function foo() {
console.log(this);
}
// new : 새로운 객체가 생성되서 실행된다.
new foo(); // foo{}
new를 이용해서 함수를 생성하면 비어있는 this 객체가 할당되고
속성을 지정해주면 객체에 속성이 들어간 채로 this 객체를 반환하게 된다.
function foo() {
// new로 생성하면 주석 부분이 자동으로 된다고 생각하면 된다.
// this = {};
this.name = 'jasn';
// {
// name: 'jasn'
// }
// return this;
}
// new : 새로운 객체가 생성되서 실행된다.
let jasn = new foo(); // foo{}
console.log(jasn); // foo { name: 'jasn' }
아래와 같이 객체를 생성할 때 인자를 넘겨서 속성을 지정해줄 수도 있다.
function foo(name) {
// new로 생성하면 주석 부분이 자동으로 된다고 생각하면 된다.
// this = {};
this.name = name;
// {
// name: 'jasn'
// }
// return this;
}
// new : 새로운 객체가 생성되서 실행된다.
let jasn = new foo('jasn'); // foo{}
console.log(jasn); // foo { name: 'jasn' }
new를 써서 만드는 함수를 보통 생성자 함수라고 하고
생성자 함수의 첫 글자는 보통 대문자로 작성한다.
이 때, 만들어진 객체를 인스턴스(instance) 라고 부른다.
function Person(name, age) {
this.name = name;
this.age = age;
}
// new는 별개의 새로운 객체를 생성
// 새로 만들어진 객체를 인스턴스(instance) 라고 부른다
let jasn = new Person('jasn', 31);
let ken = new Person('ken', 34);
console.log(jasn); // Person { name: 'jasn', age: 31 }
console.log(ken); // Person { name: 'ken', age: 34 }
Reference
www.youtube.com/watch?v=ayyuU0xdbIU&t=71s
developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/globalThis
'FRONTEND > Javascript' 카테고리의 다른 글
[Javascript] primitive type(기본 타입) (0) | 2021.05.01 |
---|---|
[Javascript] async / defer (0) | 2021.04.30 |
[Javascript] 배열 추가 / 삭제 정리 (push, unshift, pop, shift, slice, filter, splice, length) (0) | 2021.04.24 |
[Javascript] 최대값 / 최소값 구하기 (0) | 2021.04.23 |
[Javascript] D-day 계산기 (0) | 2021.04.23 |
댓글