Languages/JavaScript

[HUFS/GnuVil] #11 strict mode, 빌트인 객체, this

성중 2022. 10. 13. 14:00

strict mode

function foo() {
  x = 10;
}
foo();

console.log(x); // 10

위 코드는 실행이 안될 것 같지만 x가 암묵적 전역으로 들어가며 문제없이 실행된다

 

'use strict';

function foo() {
  x = 10; // ReferenceError: x is not defined
}
foo();

ES5부터 strict mode를 위와 같이 활성화해 의도적으로 에러를 발생시킬 수 있다

* 암묵적 전역 / delete 연산자 사용 / 매개변수 이름 중복 / with 문의 사용 등

 

ESLint의 오류 리포팅

컨벤션을 커스텀해 적용할 수 있는 ESLint 등의 린트 도구를 사용하는 것이 더 적절하다

 

빌트인 객체

자바스크립트 객체의 분류

표준 빌트인 객체는 object, String, Number, Boolean, Symbol, Date, Math, RegExp, Array, Map/Set, WeakMap/WeakSet, Function, Promise, Reflect, Proxy, JSON, Error 등 자바스크립트가 제공하는 40여개의 ES 사양에 정의된 객체이다.

 

// String 생성자 함수에 의한 String 객체 생성
const strObj = new String('Lee'); // String {"Lee"}
console.log(typeof strObj);       // object

// Number 생성자 함수에 의한 Number 객체 생성
const numObj = new Number(123); // Number {123}
console.log(typeof numObj);     // object

// Boolean 생성자 함수에 의한 Boolean 객체 생성
const boolObj= new Boolean(true); // Boolean {true}
console.log(typeof boolObj);      // object

// Function 생성자 함수에 의한 Function 객체(함수) 생성
const func = new Function('x', 'return x * x'); // ƒ anonymous(x )
console.log(typeof func);                       // function

// Array 생성자 함수에 의한 Array 객체(배열) 생성
const arr = new Array(1, 2, 3); // (3) [1, 2, 3]
console.log(typeof arr);        // object

// RegExp 생성자 함수에 의한 RegExp 객체(정규 표현식) 생성
const regExp = new RegExp(/ab+c/i); // /ab+c/i
console.log(typeof regExp);         // object

// Date 생성자 함수에 의한 Date 객체 생성
const date = new Date();  // Fri May 08 2020 10:43:25 GMT+0900 (대한민국 표준시)
console.log(typeof date); // object

이 중 Math, Reflect, JSON을 제외한 표준 빌트인 객체는 모두 인스턴스를 생성할 수 있는 생성자 함수 객체다

 

// 브라우저 환경
globalThis === this   // true
globalThis === window // true
globalThis === self   // true
globalThis === frames // true

// Node.js 환경(12.0.0 이상)
globalThis === this   // true
globalThis === global // true

전역 객체(global object)는 코드가 실행되기 전 가장 먼저 생성되는 특수한 객체이며, 어떤 객체에도 속하지 않은 최상위 객체이다. Infinity / NaN / undefined 등의 전역 프로퍼티를 가지며 eval / isFinite / isNaN / parseFloat / encodeURI / decodeURI 등의 전역 메서드를 가진다

 

var x = 10; // 전역 변수

function foo () {
  // 선언하지 않은 식별자에 값을 할당
  y = 20; // window.y = 20;
}
foo();

// 선언하지 않은 식별자 y를 전역에서 참조할 수 있다.
console.log(x + y); // 30

선언하지 않은 식별자에 값을 할당하는 것이 전역 객체 프로퍼티 생성으로 해석되는 암묵적 전역을 주의하자

 

this

this자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수로, this를 통해 자신이 속한 객체 또는 자신이 생성할 인스턴스의 프로퍼티나 메서드를 참조할 수 있다

// 객체 리터럴
const circle = {
  radius: 5,
  getDiameter() {
    // this는 메서드를 호출한 객체를 가리킨다.
    return 2 * this.radius;
  }
};

console.log(circle.getDiameter()); // 10

이 때, this 바인딩이란 this와 this가 가리킬 객체가 식별자와 값으로 연결되는 것을 뜻한다

 

// 생성자 함수
function Circle(radius) {
  // this는 생성자 함수가 생성할 인스턴스를 가리킨다.
  this.radius = radius;
}

Circle.prototype.getDiameter = function () {
  // this는 생성자 함수가 생성할 인스턴스를 가리킨다.
  return 2 * this.radius;
};

// 인스턴스 생성
const circle = new Circle(5);
console.log(circle.getDiameter()); // 10

생성자 함수 내부의 this는 생성자 함수가 생성할 인스턴스를 가리킨다. 즉, this는 상황에 따라 가리키는 대상이 다르다 = 호출할 때 동적으로 결정된다 (일반적으로 객체의 메서드 내부 또는 생성자 함수 내부에서만 사용)

 

var value = 1;

const obj = {
  value: 100,
  foo() {
    console.log("foo's this: ", this); // {value: 100, foo: ƒ}
    // 콜백 함수 내부의 this에는 전역 객체가 바인딩된다.
    setTimeout(function () {
      console.log("callback's this: ", this); // window
      console.log("callback's this.value: ", this.value); // 1
    }, 100);
  }
};

obj.foo();

대부분 일반 함수에 this가 호출되면 전역 객체가 바인딩되어 큰 의미가 없다 (일부 예외)

 

함수 호출 방식에 따른 this 바인딩

 

 내용은 위키북스의 '모던 자바스크립트 Deep Dive' 바탕으로 작성되었습니다.