ECMAScript는 객체 지향 프로그래밍 언어로, 호스트 환경 내에서 계산을 수행하고 계산 객체를 조작합니다. 여기 정의된 ECMAScript는 계산적으로 자급자족하도록 설계된 것이 아니며, 외부 데이터 입력이나 계산 결과 출력에 대한 규정이 없습니다. 대신 ECMAScript 프로그램의 계산 환경은 이 명세서에 기술된 객체와 기타 기능뿐만 아니라 환경 특화 객체도 제공하는 것이 기대되며, 이들의 설명 및 동작은 이 명세서 범위를 벗어나지만 ECMAScript 프로그램에서 접근 가능한 프로퍼티와 호출 가능한 함수가 있을 수 있음을 나타냅니다.
ECMAScript는 원래 스크립트 언어로 설계되었지만, 현재는 범용 프로그래밍 언어로 널리 사용됩니다. 스크립트 언어란 기존 시스템의 기능을 조작, 맞춤화, 자동화하는 데 사용하는 프로그래밍 언어입니다. 이러한 시스템에서는 이미 사용자 인터페이스를 통해 유용한 기능이 제공되며, 스크립트 언어는 해당 기능을 프로그램 제어로 노출하는 역할을 합니다. 이처럼 기존 시스템은 객체와 기능을 제공하는 호스트 환경을 구성하며, 이는 스크립트 언어의 기능을 완성합니다. 스크립트 언어는 전문 프로그래머와 비전문 프로그래머 모두 사용할 수 있도록 설계되었습니다.
ECMAScript는 원래 웹 스크립트 언어로 설계되어, 브라우저에서 웹 페이지에 생동감을 더하고 웹 기반 클라이언트-서버 아키텍처의 일부로 서버 계산을 수행하는 메커니즘을 제공했습니다. ECMAScript는 현재 다양한 호스트 환경에서 핵심 스크립트 기능을 제공합니다. 따라서 핵심 언어는 특정 호스트 환경과 분리되어 이 문서에서 정의됩니다.
ECMAScript 사용은 단순한 스크립팅을 넘어 다양한 환경과 규모에서 전체 프로그래밍 작업 영역으로 확장되었습니다. 사용이 늘어남에 따라 ECMAScript가 제공하는 기능과 시설도 확대되었습니다. ECMAScript는 이제 완전한 기능의 범용 프로그래밍 언어입니다.
4.1 웹 스크립팅
웹 브라우저는 클라이언트 측 계산을 위한 ECMAScript 호스트 환경을 제공합니다. 예를 들어, 창, 메뉴, 팝업, 대화 상자, 텍스트 영역, 앵커, 프레임, 히스토리, 쿠키, 입출력 등을 나타내는 객체를 포함합니다. 또한 호스트 환경은 포커스 변경, 페이지/이미지 로딩 및 언로드, 오류 및 중단, 선택, 폼 제출, 마우스 동작과 같은 이벤트에 스크립트 코드를 연결할 수 있는 수단을 제공합니다. 스크립트 코드는 HTML 내에 나타나며, 표시되는 페이지는 UI 요소와 고정 및 계산된 텍스트/이미지의 조합입니다. 스크립트 코드는 사용자 상호작용에 반응하며, 메인 프로그램이 필요하지 않습니다.
웹 서버는 서버 측 계산을 위한 다른 호스트 환경을 제공하며, 요청, 클라이언트, 파일을 나타내는 객체와 데이터 잠금/공유 메커니즘을 포함합니다. 브라우저 측과 서버 측 스크립팅을 함께 사용하면, 클라이언트와 서버 간에 계산을 분산시키면서 웹 기반 애플리케이션에 맞춤화된 사용자 인터페이스를 제공할 수 있습니다.
ECMAScript를 지원하는 각 웹 브라우저와 서버는 자체 호스트 환경을 제공하며, 이것이 ECMAScript 실행 환경을 완성합니다.
4.2 호스트와 구현체
ECMAScript를 호스트 환경에 통합하기 위해, 이 명세서는 일부 기능(예: 추상 연산)의 정의를 전적으로 또는 부분적으로 명세서 외부 소스에 위임합니다. 편집상, 이 명세서는 다음과 같은 위임 종류를 구분합니다.
구현체란 부록 D에 나열된 시설이나 구현 정의 또는 구현 근사로 표시된 시설을 추가적으로 정의하는 외부 소스를 의미합니다. 비공식적으로 구현체는 특정 웹 브라우저와 같은 구체적인 산출물을 가리킵니다.
구현 정의 시설은 외부 소스에 정의를 위임하며 추가적인 자격을 두지 않습니다. 이 명세서는 특정 동작에 대해 권고하지 않으며, 적합한 구현은 명세서가 제시한 제한 내에서 자유롭게 동작을 선택할 수 있습니다.
구현 근사 시설은 외부 소스에 정의를 위임하면서 이상적인 동작을 권장합니다. 적합한 구현은 명세서의 제한 내에서 자유롭게 동작을 선택할 수 있지만, 이상적인 동작을 최대한 근사하도록 권장됩니다. 예를 들어 Math.exp와 같은 수학 연산이 구현 근사입니다.
호스트는 부록 D에 나열된 시설을 추가적으로 정의하지만, 기타 구현 정의 또는 구현 근사 시설은 추가적으로 정의하지 않는 외부 소스입니다. 비공식적으로 호스트는 이 명세서와 부록 D를 통해 동일하게 인터페이스하는 모든 웹 브라우저 집합 등, 모든 구현체 집합을 의미합니다. 호스트는 종종 WHATWG HTML(https://html.spec.whatwg.org/)과 같은 외부 명세서입니다. 즉, 호스트 정의 시설은 종종 외부 명세서에서 추가적으로 정의됩니다.
호스트 후크는 전적으로 또는 부분적으로 외부 소스에 의해 정의되는 추상 연산입니다. 모든 호스트 후크는 부록 D에 나열되어야 합니다. 호스트 후크는 최소한 다음 요구 사항을 충족해야 합니다:
정상 완료 또는 throw 완료 중 하나를 반환해야 합니다.
호스트 정의 시설은 추가적인 자격 없이 외부 소스에 정의를 위임하며, 부록 D에 나열되어 있습니다. 호스트가 아닌 구현체도 호스트 정의 시설에 대한 정의를 제공할 수 있습니다.
호스트 환경은 모든 호스트 정의 시설에 대한 선택적 정의입니다. 호스트 환경에는 일반적으로 입력을 얻거나 출력을 제공하는 객체나 함수가 포함되어 있으며, 전역 객체의 호스트 정의 프로퍼티로 제공됩니다.
이 명세서는 항상 가장 구체적인 용어를 사용하는 편집 관례를 따릅니다. 예를 들어, 어떤 시설이 호스트 정의인 경우 구현 정의로 지칭하지 않습니다.
호스트와 구현체 모두 이 명세서에서 정의된 언어 타입, 명세 타입, 추상 연산, 문법 생성, 내장 객체, 내장 심볼을 통해 이 명세서와 인터페이스할 수 있습니다.
4.3 ECMAScript 개요
아래는 ECMAScript에 대한 비공식 개요이며, 언어의 모든 부분이 기술된 것은 아닙니다. 이 개요는 표준의 일부가 아닙니다.
ECMAScript는 객체 기반입니다. 기본 언어와 호스트 기능은 객체로 제공되며, ECMAScript 프로그램은 상호 통신하는 객체 집합입니다. ECMAScript에서 객체란 0개 이상의 프로퍼티로 구성되어 있으며, 각 프로퍼티에는 프로퍼티의 사용 방법을 결정하는 특성이 있습니다. 예를 들어, 어떤 프로퍼티의 Writable 특성이 false로 설정된 경우, ECMAScript 코드가 해당 프로퍼티에 다른 값을 할당하려고 하면 실패합니다. 프로퍼티는 다른 객체, 원시값 또는 함수를 담는 컨테이너입니다. 원시값은 내장 타입 Undefined, Null, Boolean, Number, BigInt, String, Symbol; 중 하나의 멤버입니다. 객체는 내장 타입 Object의 멤버이며, 함수는 호출 가능한 객체입니다. 객체의 프로퍼티에 연결된 함수는 메서드라고 부릅니다.
ECMAScript는 ECMAScript 엔티티 정의를 완성하는 내장 객체 집합을 정의합니다. 내장 객체에는 전역 객체, 언어의 런타임 의미에 필수적인 Object, Function, Boolean, Symbol 및 다양한 Error 객체, 숫자값을 나타내고 조작하는 Math, Number, Date 객체, 텍스트 처리를 위한 String 및 RegExp 객체, 값을 인덱싱하는 컬렉션인 Array와 9가지 Typed Array, 키 기반 컬렉션인 Map과 Set 객체, 구조화 데이터를 지원하는 JSON 객체, ArrayBuffer, SharedArrayBuffer, DataView, 제어 추상화를 지원하는 제너레이터 함수와 Promise 객체, 그리고 리플렉션을 위한 Proxy 및 Reflect 객체가 포함됩니다.
ECMAScript는 내장 연산자 집합도 정의합니다. ECMAScript 연산자에는 다양한 단항 연산, 곱셈 연산자, 덧셈 연산자, 비트 이동 연산자, 관계 연산자, 동등 연산자, 이진 비트 연산자, 이진 논리 연산자, 할당 연산자, 쉼표 연산자가 포함됩니다.
대규모 ECMAScript 프로그램은 모듈을 통해 여러 문/선언 시퀀스로 분할될 수 있습니다. 각 모듈은 다른 모듈에서 제공해야 하는 선언과 다른 모듈에서 사용할 수 있는 자신의 선언을 명확히 식별합니다.
ECMAScript 문법은 의도적으로 Java 문법과 유사하게 설계되었습니다. ECMAScript 문법은 스크립트 언어로 쉽게 사용할 수 있도록 완화되어 있습니다. 예를 들어, 변수에 타입 선언이 필요하지 않으며, 프로퍼티에 타입이 연결되지 않고, 함수 선언이 호출보다 먼저 나타나야 할 필요도 없습니다.
4.3.1 객체
ECMAScript는 클래스 정의 문법을 포함하지만, ECMAScript 객체는 C++, Smalltalk, Java와 같은 클래스 기반 언어처럼 근본적으로 클래스 기반이 아닙니다. 객체는 리터럴 표기 또는 객체를 생성하고 프로퍼티의 초기값을 할당하는 생성자를 통해 여러 방식으로 생성될 수 있습니다. 각 생성자는 "prototype"이라는 프로퍼티를 가진 함수로, 프로토타입 기반 상속과 공유 프로퍼티를 구현하는 데 사용됩니다. new 표현식으로 생성자를 사용하면 객체가 생성됩니다. 예를 들어, new Date(2009, 11)은 새로운 Date 객체를 만듭니다. 생성자를 new 없이 호출하면 생성자마다 다른 결과가 발생합니다. 예를 들어, Date()는 객체가 아닌 현재 날짜와 시간의 문자열 표현을 반환합니다.
생성자로 생성된 모든 객체는 암시적으로 자신이 속한 생성자의 "prototype" 프로퍼티 값에 대한 참조(객체의 프로토타입이라 부름)를 갖습니다. 또한 프로토타입은 자신만의 non-null 암시적 참조를 가질 수 있으며, 이를 프로토타입 체인이라 부릅니다. 객체에서 프로퍼티에 대한 참조가 발생하면, 해당 이름의 프로퍼티를 가진 프로토타입 체인에서 첫 번째 객체의 프로퍼티가 참조됩니다. 즉, 먼저 직접 지정된 객체에서 해당 프로퍼티가 있는지 확인하고, 있으면 그 프로퍼티가 참조 대상이 됩니다. 없으면 해당 객체의 프로토타입을 다음으로 검사하고, 계속 반복합니다.
Figure 1: 객체/프로토타입 관계
클래스 기반 객체 지향 언어에서는 일반적으로 상태는 인스턴스가, 메서드는 클래스가 담당하며, 상속은 구조와 동작에만 적용됩니다. ECMAScript에서는 상태와 메서드가 객체에 담기며, 구조, 동작, 상태 모두가 상속됩니다.
프로토타입에 특정 프로퍼티가 있고, 객체에 직접 해당 프로퍼티가 포함되지 않은 모든 객체는 그 프로퍼티와 값을 공유합니다. 그림 1은 이를 보여줍니다:
CF는 생성자(동시에 객체)입니다. cf1, cf2, cf3, cf4, cf5 등 5개의 객체가 new 표현식으로 생성되었습니다. 각 객체에는 "q1", "q2" 프로퍼티가 있습니다. 점선은 암시적 프로토타입 관계를 나타냅니다. 예를 들어, cf3의 프로토타입은 CFp입니다. 생성자인 CF는 "P1", "P2"라는 두 개의 프로퍼티를 갖지만, CFp, cf1, cf2, cf3, cf4, cf5에서는 보이지 않습니다. CFp의 "CFP1" 프로퍼티는 cf1, cf2, cf3, cf4, cf5에서 공유됩니다(CF에서는 공유되지 않음). CFp의 암시적 프로토타입 체인에 있는 다른 프로퍼티도 "q1", "q2", "CFP1"이 아닌 경우 공유됩니다. CF와 CFp 사이에는 암시적 프로토타입 링크가 없습니다.
대부분의 클래스 기반 객체 언어와 달리, 객체에는 값을 할당함으로써 동적으로 프로퍼티를 추가할 수 있습니다. 즉, 생성자는 생성된 객체의 모든 프로퍼티를 반드시 명명하거나 값을 할당할 필요가 없습니다. 위 그림에서 cf1, cf2, cf3, cf4, cf5에 대해 CFp에 새 값을 할당함으로써 새로운 공유 프로퍼티를 추가할 수 있습니다.
ECMAScript 객체는 본질적으로 클래스 기반이 아니지만, 생성자 함수, 프로토타입 객체, 메서드의 공통 패턴에 기반하여 클래스 유사 추상을 정의하는 것이 편리할 때가 많습니다. ECMAScript 내장 객체도 이런 클래스 유사 패턴을 따릅니다. ECMAScript 2015부터는 내장 객체가 사용하는 동일한 클래스 유사 추상 패턴에 맞는 객체를 간결하게 정의할 수 있는 문법적 클래스 정의가 도입되었습니다.
4.3.2 ECMAScript의 엄격 변종
ECMAScript 언어는 일부 사용자가 언어에서 제공되는 특정 기능 사용을 제한하고자 할 수 있음을 인식합니다. 이는 보안, 오류 발생 가능성이 높은 기능 회피, 오류 검사 강화 또는 기타 사용자의 목적을 위해서일 수 있습니다. 이런 가능성을 지원하기 위해 ECMAScript는 언어의 엄격 변종을 정의합니다. 엄격 변종은 일반 ECMAScript 언어의 일부 구문 및 의미론적 기능을 제외하고, 일부 기능의 상세 의미론을 수정합니다. 엄격 변종은 비엄격 언어 형식에서는 오류로 지정되지 않은 상황에서도 오류 예외를 반드시 던져야 하는 추가 오류 조건을 명시합니다.
ECMAScript의 엄격 변종은 언어의 엄격 모드로 일반적으로 불립니다. 엄격 모드의 선택과 엄격 모드 구문 및 의미론 사용은 개별 ECMAScript 소스 텍스트 단위 수준에서 명시적으로 결정됩니다(11.2.2 참조). 엄격 모드는 구문적 소스 텍스트 단위 수준에서 선택되므로, 제한은 해당 소스 텍스트 단위 내에서만 국지적으로 적용됩니다. 엄격 모드는 여러 소스 텍스트 단위에 걸쳐 일관되게 동작해야 하는 ECMAScript 의미론의 어떤 측면도 제한하거나 수정하지 않습니다. 전체 ECMAScript 프로그램은 엄격 모드와 비엄격 모드 소스 텍스트 단위로 구성될 수 있으며, 이 경우 엄격 모드는 실제로 엄격 모드 소스 텍스트 단위 내에서 정의된 코드를 실행할 때만 적용됩니다.
이 명세서에 적합하려면 ECMAScript 구현은 이 명세서에서 정의한 완전한 비제한 ECMAScript 언어와 엄격 변종을 모두 구현해야 합니다. 또한, 구현체는 비제한 모드와 엄격 모드 소스 텍스트 단위를 단일 복합 프로그램으로 조합하는 기능을 지원해야 합니다.
4.4 용어와 정의
이 문서의 목적상, 아래 용어와 정의가 적용됩니다.
4.4.1 구현 근사
구현 근사 시설은 전체 또는 일부가 외부 소스에 의해 정의되지만, 이 명세서에서 권장되는 이상적 동작을 갖습니다.
생성자의 "prototype" 프로퍼티 값은 상속 및 공유 프로퍼티 구현에 사용되는 프로토타입 객체입니다.
4.4.8 프로토타입
다른 객체를 위한 공유 프로퍼티를 제공하는 객체
Note
생성자가 객체를 생성할 때, 해당 객체는 프로퍼티 참조 해결을 위해 생성자의 "prototype" 프로퍼티를 암시적으로 참조합니다. 생성자의 "prototype" 프로퍼티는 constructor.prototype 표현식으로 참조할 수 있으며, 프로토타입에 추가된 프로퍼티는 프로토타입을 공유하는 모든 객체에 상속을 통해 공유됩니다. 또는 Object.create 내장 함수를 사용하여 명시적으로 지정된 프로토타입으로 새 객체를 만들 수 있습니다.
String 객체는 String 생성자를 new 표현식으로 사용할 때 생성되며, String 값을 인자로 제공합니다. 결과 객체는 내부 슬롯에 String 값이 저장됩니다. String 객체는 String 생성자를 함수처럼 호출하면 String 값으로 강제 변환될 수 있습니다(22.1.1.1).
Number 객체는 Number 생성자를 new 표현식으로 사용할 때 생성되며, Number 값을 인자로 제공합니다. 결과 객체는 내부 슬롯에 Number 값이 저장됩니다. Number 객체는 Number 생성자를 함수처럼 호출하면 Number 값으로 강제 변환될 수 있습니다(21.1.1.1).