5 식 및 연산자

source: categories/study/javascript-mdn/javascript-mdn5.md

식 및 연산자

이 장은 자바스크립트의 모든 연산자, 식 및 키워드를 나타냅니다.

this

자바스크립트에서 함수의 this 키워드는 다른 언어와 조금 다르게 동작합니다.
또한 엄격모드(strict mode)와 비엄격 모드에서도 일부 차이가 있습니다.

대부분의 경우 this의 값은 함수를 호출한 방법에 의해 결정됩니다.
실행중에는 할당으로 설정할 수 없고 함수를 호출할 때마다 다를 수 있습니다.
ES5는 함수를 어덯게 호출했는지 상관하지 않고 this 값을 설정할 수 있는 bind 메소드를 도입했고,
ES2015는 스스로의 this 바인딩을 제공하지 않는 화살표 함수를 추가했습니다. (이는 렉시컬 컨텍스트 안의 this 값을 유지합니다.)

const test = {
    prop: 42,
    func: function () {
        return this.prop;
    }
}

console.log(test.func()); // expected output: 42

this

실행 컨텍스트(global, function 또는 eval)의 프로퍼티는 비엄격 모드에서 항상 객체를 참조하며, 엄격 모드에서는 어떠한 값이든 될 수 있습니다.

전역 문맥

전역 실행 맥락에서 this는 엄격 모드 여부에 관계없이 전역 객체를 참조합니다.

// 웹 브라우저에서는 window 객체가 전역 객체
console.log(this === window); // true

a = 37;
console.log(window.a); // 37

this.b = "MDN";
console.log(window.b)  // "MDN"
console.log(b)         // "MDN"
Note

노트: globalThis 프로퍼티를 사용하여 코드가 실행중인 현재 컨텍스트와 관계없이 항상 전역 객체를 얻을 수 있습니다.

globalThis

전역 globalThis 속성은 this 값을 가진 전역 객체를 반환합니다.

function canMakeHTTPRequest() {
  return typeof globalThis.XMLHttpRequest === 'function';
}

console.log(canMakeHTTPRequest());
// expected output (in a browser): true
Property attributes of globalThis  
Writable (쓰기가능) yes
Enumerable (열거가능) no
Configurable (구성가능) yes

globalThis - 설명

역사적으로, 서로 다른 자바스크립트 환경의 전역 범위에 접근하는건 서로 다른 구문을 필요로 했습니다.
웹에서는 window, self, frames(en-US)를 사용할 수 있지만, Web Workers에서는 self만 동작합니다.
Node.js에서는 아무것도 쓸 수 없고, 대신 global을 사용해야 합니다.
비엄격 모드에서의 함수 내부에서 this를 사용할 수도 있겠지만, 모듈이나 엄격 모드의 함수에서는 undefined를 가리키는 문제가 있습니다.
Function('return this')()를 사용하는 방법도 존재하지만, 브라우저의 CSP 등으로 eval()을 사용할 수 없는 환경에서는 Function도 이렇게 사용할 수 없습니다.

globalThis - CSP

CSP(Content Security Policy)는 XSS (en-US)이나 데이터 주입과 같은 특정 웹사이트 관련 공격을 탐지하거나 완화하기 위해 사용된다.

기본적인 구현은 Content-Security-Policy라고 불리는 HTTP헤더를 기반으로 한다.

globalThis 속성은 환경에 무관하게 전역 this 값, 즉 전역 객체에 접근하는 표준 방법을 제공합니다.
window, self 등 비슷한 속성과는 다르게 브라우저/비 브라우저 맥락 모두에서의 동작을 보장합니다.
따라서 코드를 구동하는 환경을 모르더라도 전역 객체에 일관적으로 접근할 수 있습니다.

globalThis - HTML과 WindowProxy

많은 자바스크립트 엔진에서 globalThis는 실제 전역 객체를 가리킬 것이나, 웹 브라우저는 <iframe>과 교차 창 보안 문제로 인하여 전역 객체를 감싼 Proxy를 대신 가리키고, 실제 객체에는 직접 접근할 수 없습니다.
일반적인 사용에는 차이가 없다고 봐도 무방하지만, 알아두는 것이 중요합니다.

globalThis - 이름

selfglobal처럼, 다른 인기있던 제안은 기존 코드와의 호환성 문제를 우려해 제외되었습니다.
언어 제안서의 Naming 문서를 방문해 더 자세한 정보를 읽어보세요.

globalThis - 예제

globalThis없이 현재 환경의 전역 객체를 가져오는 방법 중 유일하게 믿을만한 방법은 Function('return this')()입니다.
그러나 일부 환경에서는 CSP(en-US) 위반에 걸리는 코드이므로, 그 대신 es6-shim으로 다음 검사를 수행합니다.

Note

es6-shim

레거시 자바스크립트 엔진이 ECMAScript 6(Harmony)에 최대한 가깝게 작동하도록 호환성 shim을 제공합니다.

var getGlobal = function () {
  if (typeof self !== 'undefined') { return self; }
  if (typeof window !== 'undefined') { return window; }
  if (typeof global !== 'undefined') { return global; }
  throw new Error('unable to locate global object');
};

var globals = getGlobal();

if (typeof globals.setTimeout !== 'function') {
  // no setTimeout in this environment!
}

globalThis를 사용할 수 있으면 환경별 전역 객체 검사는 더 이상 필요하지 않습니다.

if (typeof globalThis.setTimeout !== 'function') {
  // no setTimeout in this environment!
}

함수 문맥

함수 내부에서 this의 값은 함수를 호출한 방법에 의해 좌우됩니다.

단순 호출

다음 예제는 엄격 모드가 아니며 this의 값이 호출에 의해 설정되지 않으므로, 기본값으로 브라우저에서는 window인 전역 객체를 참조합니다.

https://developer.mozilla.org/ko/docs/Web/JavaScript/A_re-introduction_to_JavaScript

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/this