Environment Record는 ECMAScript 코드의 어휘적 중첩 구조를 바탕으로 Identifier를 특정 변수 및 함수와 연관시키는 것을 정의하는 데 사용되는 명세 타입이다. 보통 Environment Record는 FunctionDeclaration, BlockStatement, 또는 TryStatement의 Catch 절과 같은 ECMAScript 코드의 특정 구문 구조와 연관된다. 이러한 코드가 평가될 때마다, 해당 코드에 의해 생성되는 식별자 바인딩을 기록하기 위해 새로운 Environment Record가 생성된다.
모든 Environment Record는 [[OuterEnv]] 필드를 가지며, 그 값은 null 또는 바깥쪽 Environment Record에 대한 참조이다. 이것은 Environment Record 값들의 논리적 중첩을 모델링하는 데 사용된다. 어떤 (안쪽) Environment Record의 outer reference는 그 안쪽 Environment Record를 논리적으로 둘러싸는 Environment Record에 대한 참조이다. 바깥쪽 Environment Record는 물론 자기 자신의 바깥쪽 Environment Record를 가질 수 있다. 하나의 Environment Record는 여러 안쪽 Environment Record의 outer environment 역할을 할 수 있다. 예를 들어, FunctionDeclaration이 두 개의 중첩된 FunctionDeclaration을 포함한다면, 각 중첩 함수의 Environment Record는 둘러싸고 있는 함수의 현재 평가에 대한 Environment Record를 자신의 outer Environment Record로 가진다.
Environment Record는 순전히 명세 메커니즘이며, ECMAScript 구현의 어떤 특정 산출물과 대응할 필요는 없다. ECMAScript 프로그램이 이러한 값에 직접 접근하거나 조작하는 것은 불가능하다.
Function Environment Record는 ECMAScript 함수 객체의 호출에 대응하며, 그 함수 내부의 최상위 선언에 대한 바인딩을 포함한다. 이는 새로운 this 바인딩을 설정할 수 있다. 또한 super 메서드 호출을 지원하는 데 필요한 상태도 포착한다.
Global Environment Record는 Script의 전역 선언에 사용된다. 이것은 바깥 환경을 가지지 않으며, 그 [[OuterEnv]]는 null이다. 식별자 바인딩으로 미리 채워질 수 있으며, 그 프로퍼티가 전역 환경의 일부 식별자 바인딩을 제공하는 연관된 전역 객체를 포함한다. ECMAScript 코드가 실행됨에 따라 추가 프로퍼티가 전역 객체에 추가될 수 있고 초기 프로퍼티가 수정될 수 있다.
Environment Record 추상 클래스는 Table 14에 정의된 추상 명세 메서드를 포함한다. 이 추상 메서드들은 각 구체적 서브클래스에 대해 서로 다른 구체 알고리즘을 가진다.
The abstract method CreateMutableBinding takes arguments name (a String) and deletable (a Boolean) and returns either a normal completion containing unused or a throw completion.
이것은 Environment Record 안에 초기화되지 않은 새로운 가변 바인딩을 생성한다. name은 바인딩된 이름의 텍스트이다. deletable이 true이면 그 바인딩은 이후 삭제될 수 있다.
The abstract method CreateImmutableBinding takes arguments name (a String) and strict (a Boolean) and returns either a normal completion containing unused or a throw completion.
이것은 Environment Record 안에 초기화되지 않은 새로운 불변 바인딩을 생성한다. name은 바인딩된 이름의 텍스트이다. strict이 true이면, 그것이 초기화된 후 값을 설정하려는 시도는 그 바인딩을 참조하는 연산의 strict mode 설정과 관계없이 항상 예외를 던진다.
The abstract method InitializeBinding takes arguments name (a String) and value (an ECMAScript language value) and returns either a normal completion containing unused or a throw completion.
이것은 Environment Record 안에 이미 존재하지만 아직 초기화되지 않은 바인딩의 값을 설정한다. name은 바인딩된 이름의 텍스트이다. value는 그 바인딩에 대한 값이다.
The abstract method SetMutableBinding takes arguments name (a String), value (an ECMAScript language value), and strict (a Boolean) and returns either a normal completion containing unused or a throw completion.
이것은 Environment Record 안에 이미 존재하는 가변 바인딩의 값을 설정한다. name은 바인딩된 이름의 텍스트이다. value는 그 바인딩에 대한 값이다. strict이 true이고 바인딩을 설정할 수 없으면, 이것은 TypeError 예외를 던진다.
The abstract method GetBindingValue takes arguments name (a String) and strict (a Boolean) and returns either a normal completion containing an ECMAScript language value or a throw completion.
이것은 Environment Record에서 이미 존재하는 바인딩의 값을 반환한다. name은 바인딩된 이름의 텍스트이다. strict은 strict mode 코드에서 유래한 참조이거나 그 밖에 strict mode 참조 의미론을 요구하는 참조를 식별하는 데 사용된다. strict이 true이고 바인딩이 존재하지 않으면, 이것은 ReferenceError 예외를 던진다. 바인딩이 존재하지만 초기화되지 않았다면, strict의 값과 관계없이 ReferenceError가 던져진다.
The abstract method DeleteBinding takes argument name (a String) and returns either a normal completion containing a Boolean or a throw completion.
이것은 Environment Record에서 바인딩을 삭제한다. name은 바인딩된 이름의 텍스트이다. name에 대한 바인딩이 존재하면, 이것은 그 바인딩을 제거하고 true를 반환한다. 바인딩이 존재하지만 제거할 수 없으면, 이것은 false를 반환한다. 바인딩이 존재하지 않으면, 이것은 true를 반환한다.
The abstract method GetThisBinding takes no arguments and returns either a normal completion containing an ECMAScript language value or a throw completion.
이것은 이 Environment Record의 this 바인딩 값을 반환한다. this 바인딩이 초기화되지 않았다면 ReferenceError를 던진다.
각 Declarative Environment Record는 변수, 상수, let, class, module, import 및/또는 함수 선언을 포함하는 ECMAScript 프로그램 스코프와 연관된다. Declarative Environment Record는 그 스코프 안에 포함된 선언들이 정의하는 식별자 집합을 바인딩한다.
9.1.1.1.1 HasBinding ( name )
The HasBinding concrete method of a Declarative Environment RecordenvRec takes argument name (a String) and returns a normal completion containing a Boolean. 이것은 인수 식별자가 record에 의해 바인딩된 식별자들 중 하나인지 결정한다. It performs the following steps when called:
The CreateMutableBinding concrete method of a Declarative Environment RecordenvRec takes arguments name (a String) and deletable (a Boolean) and returns a normal completion containing unused. 이것은 name이라는 이름에 대해 초기화되지 않은 새로운 가변 바인딩을 생성한다. 이 Environment Record 안에는 name에 대한 바인딩이 이미 존재해서는 안 된다. deletable이 true이면, 새 바인딩은 삭제 가능 대상으로 표시된다. It performs the following steps when called:
envRec 안에 name에 대한 가변 바인딩을 생성하고, 그것이 초기화되지 않았음을 기록한다. deletable이 true이면, 새로 생성된 바인딩이 이후 DeleteBinding 호출에 의해 삭제될 수 있음을 기록한다.
unused를 반환한다.
9.1.1.1.3 CreateImmutableBinding ( name, strict )
The CreateImmutableBinding concrete method of a Declarative Environment RecordenvRec takes arguments name (a String) and strict (a Boolean) and returns a normal completion containing unused. 이것은 name이라는 이름에 대해 초기화되지 않은 새로운 불변 바인딩을 생성한다. 이 Environment Record 안에는 name에 대한 바인딩이 이미 존재해서는 안 된다. strict이 true이면, 새 바인딩은 strict 바인딩으로 표시된다. It performs the following steps when called:
envRec 안에 name에 대한 불변 바인딩을 생성하고, 그것이 초기화되지 않았음을 기록한다. strict이 true이면, 새로 생성된 바인딩이 strict 바인딩임을 기록한다.
unused를 반환한다.
9.1.1.1.4 InitializeBinding ( name, value )
The InitializeBinding concrete method of a Declarative Environment RecordenvRec takes arguments name (a String) and value (an ECMAScript language value) and returns a normal completion containing unused. 이것은 이름이 name인 식별자의 현재 바인딩 값으로 value를 설정하는 데 사용된다. name에 대한 초기화되지 않은 바인딩이 이미 존재해야 한다. It performs the following steps when called:
Assert: envRec는 name에 대한 초기화되지 않은 바인딩을 가지고 있어야 한다.
The SetMutableBinding concrete method of a Declarative Environment RecordenvRec takes arguments name (a String), value (an ECMAScript language value), and strict (a Boolean) and returns either a normal completion containing unused or a throw completion. 이것은 이름이 name인 식별자의 현재 바인딩 값을 value로 바꾸려 시도한다. 보통 name에 대한 바인딩은 이미 존재하지만, 드물게는 존재하지 않을 수도 있다. 바인딩이 불변 바인딩이면, strict이 true일 때 TypeError가 던져진다. It performs the following steps when called:
functionf() { eval("var x; x = (delete x, 0);"); }
9.1.1.1.6 GetBindingValue ( name, strict )
The GetBindingValue concrete method of a Declarative Environment RecordenvRec takes arguments name (a String) and strict (a Boolean) and returns either a normal completion containing an ECMAScript language value or a throw completion. 이것은 이름이 name인 바인딩된 식별자의 값을 반환한다. 바인딩이 존재하지만 초기화되지 않았다면, strict의 값과 관계없이 ReferenceError가 던져진다. It performs the following steps when called:
envRec 안의 name에 대한 바인딩이 초기화되지 않은 바인딩이면, ReferenceError 예외를 던진다.
envRec 안에서 현재 name에 바인딩된 값을 반환한다.
9.1.1.1.7 DeleteBinding ( name )
The DeleteBinding concrete method of a Declarative Environment RecordenvRec takes argument name (a String) and returns a normal completion containing a Boolean. 이것은 명시적으로 삭제 가능 대상으로 지정된 바인딩만 삭제할 수 있다. It performs the following steps when called:
각 Object Environment Record는 자신의 binding object라고 불리는 객체와 연관된다. Object Environment Record는 자신의 binding object의 프로퍼티 이름과 직접 대응하는 문자열 식별자 이름들의 집합을 바인딩한다. IdentifierName 형태의 문자열이 아닌 프로퍼티 키는 바인딩된 식별자 집합에 포함되지 않는다. own 프로퍼티와 상속된 프로퍼티는 [[Enumerable]] 속성의 설정과 관계없이 모두 집합에 포함된다. 객체에는 프로퍼티가 동적으로 추가되거나 삭제될 수 있으므로, Object Environment Record에 의해 바인딩되는 식별자 집합은 프로퍼티를 추가하거나 삭제하는 어떤 연산의 부작용으로 잠재적으로 변할 수 있다. 그러한 부작용의 결과로 생성되는 모든 바인딩은, 대응하는 프로퍼티의 Writable 속성이 false이더라도, 가변 바인딩으로 간주된다. 불변 바인딩은 Object Environment Record에는 존재하지 않는다.
with 문(14.11)을 위해 생성된 Object Environment Record는 함수 호출에 사용될 암묵적 this 값으로 자신의 binding object를 제공할 수 있다. 이 기능은 Boolean [[IsWithEnvironment]] 필드로 제어된다.
Object Environment Record는 Table 15에 나열된 추가 상태 필드를 가진다.
The HasBinding concrete method of an Object Environment RecordenvRec takes argument name (a String) and returns either a normal completion containing a Boolean or a throw completion. 이것은 연관된 binding object가 이름이 name인 프로퍼티를 가지는지 결정한다. It performs the following steps when called:
bindingObject를 envRec.[[BindingObject]]라고 하자.
foundBinding을 ? HasProperty(bindingObject, name)이라고 하자.
The CreateMutableBinding concrete method of an Object Environment RecordenvRec takes arguments name (a String) and deletable (a Boolean) and returns either a normal completion containing unused or a throw completion. 이것은 Environment Record와 연관된 binding object에 이름이 name인 프로퍼티를 만들고 그 값을 undefined로 초기화한다. deletable이 true이면 새 프로퍼티의 [[Configurable]] 속성은 true로 설정되고, 그렇지 않으면 false로 설정된다. It performs the following steps when called:
The InitializeBinding concrete method of an Object Environment RecordenvRec takes arguments name (a String) and value (an ECMAScript language value) and returns either a normal completion containing unused or a throw completion. 이것은 이름이 name인 식별자의 현재 바인딩 값을 value로 설정하는 데 사용된다. It performs the following steps when called:
The SetMutableBinding concrete method of an Object Environment RecordenvRec takes arguments name (a String), value (an ECMAScript language value), and strict (a Boolean) and returns either a normal completion containing unused or a throw completion. 이것은 Environment Record와 연관된 binding object에서 이름이 name인 프로퍼티의 값을 value로 설정하려 시도한다. 이름이 name인 프로퍼티는 보통 이미 존재하지만, 존재하지 않거나 현재 writable하지 않은 경우 오류 처리는 strict에 의해 결정된다. It performs the following steps when called:
bindingObject를 envRec.[[BindingObject]]라고 하자.
stillExists를 ? HasProperty(bindingObject, name)라고 하자.
The GetBindingValue concrete method of an Object Environment RecordenvRec takes arguments name (a String) and strict (a Boolean) and returns either a normal completion containing an ECMAScript language value or a throw completion. 이것은 연관된 binding object에서 이름이 name인 프로퍼티의 값을 반환한다. 그 프로퍼티는 보통 이미 존재해야 하지만, 존재하지 않는 경우 결과는 strict에 따라 달라진다. It performs the following steps when called:
The DeleteBinding concrete method of an Object Environment RecordenvRec takes argument name (a String) and returns either a normal completion containing a Boolean or a throw completion. 이것은 환경 객체의 [[Configurable]] 속성이 true인 프로퍼티에 대응하는 바인딩만 삭제할 수 있다. It performs the following steps when called:
The WithBaseObject concrete method of an Object Environment RecordenvRec takes no arguments and returns an Object or undefined. It performs the following steps when called:
Function Environment Record는 함수의 최상위 스코프를 나타내는 데 사용되는 Declarative Environment Record이며, 함수가 ArrowFunction이 아니면 this 바인딩을 제공한다. 함수가 ArrowFunction 함수가 아니고 super를 참조하면, 그 Function Environment Record는 함수 내부에서 super 메서드 호출을 수행하는 데 사용되는 상태도 포함한다.
Function Environment Record는 Table 16에 나열된 추가 상태 필드를 가진다.
The abstract operation BindThisValue takes arguments envRec (a Function Environment Record) and value (an ECMAScript language value) and returns either a normal completion containing unused or a throw completion. 이것은 envRec.[[ThisValue]]를 설정하고 그것이 초기화되었음을 기록한다. It performs the following steps when called:
Assert: envRec.[[ThisBindingStatus]]는 lexical이 아니다.
The abstract operation GetSuperBase takes argument envRec (a Function Environment Record) and returns an Object, null, or undefined. 이것은 envRec 안에 바인딩된 super 프로퍼티 접근의 기반 객체를 반환한다. 값 undefined는 그러한 접근이 런타임 오류를 발생시킬 것임을 나타낸다. It performs the following steps when called:
home을 envRec.[[FunctionObject]].[[HomeObject]]라고 하자.
Global Environment Record는 공통 realm에서 처리되는 모든 ECMAScript Script 요소가 공유하는 가장 바깥쪽 스코프를 나타내는 데 사용된다. Global Environment Record는 내장 전역(clause 19), 전역 객체의 프로퍼티, 그리고 Script 내부에 나타나는 모든 최상위 선언(8.2.9, 8.2.11)에 대한 바인딩을 제공한다.
The HasBinding concrete method of a Global Environment RecordenvRec takes argument name (a String) and returns either a normal completion containing a Boolean or a throw completion. 이것은 인수 식별자가 record에 의해 바인딩된 식별자들 중 하나인지 결정한다. It performs the following steps when called:
declarativeRecord를 envRec.[[DeclarativeRecord]]라고 하자.
The CreateMutableBinding concrete method of a Global Environment RecordenvRec takes arguments name (a String) and deletable (a Boolean) and returns either a normal completion containing unused or a throw completion. 이것은 name이라는 이름에 대해 초기화되지 않은 새로운 가변 바인딩을 생성한다. 그 바인딩은 연관된 DeclarativeRecord 안에 생성된다. DeclarativeRecord 안에는 name에 대한 바인딩이 이미 존재해서는 안 된다. deletable이 true이면, 새 바인딩은 삭제 가능 대상으로 표시된다. It performs the following steps when called:
declarativeRecord를 envRec.[[DeclarativeRecord]]라고 하자.
The CreateImmutableBinding concrete method of a Global Environment RecordenvRec takes arguments name (a String) and strict (a Boolean) and returns either a normal completion containing unused or a throw completion. 이것은 name이라는 이름에 대해 초기화되지 않은 새로운 불변 바인딩을 생성한다. 이 Environment Record 안에는 name에 대한 바인딩이 이미 존재해서는 안 된다. strict이 true이면, 새 바인딩은 strict 바인딩으로 표시된다. It performs the following steps when called:
declarativeRecord를 envRec.[[DeclarativeRecord]]라고 하자.
The InitializeBinding concrete method of a Global Environment RecordenvRec takes arguments name (a String) and value (an ECMAScript language value) and returns either a normal completion containing unused or a throw completion. 이것은 이름이 name인 식별자의 현재 바인딩 값을 value로 설정하는 데 사용된다. name에 대한 초기화되지 않은 바인딩이 이미 존재해야 한다. It performs the following steps when called:
declarativeRecord를 envRec.[[DeclarativeRecord]]라고 하자.
The SetMutableBinding concrete method of a Global Environment RecordenvRec takes arguments name (a String), value (an ECMAScript language value), and strict (a Boolean) and returns either a normal completion containing unused or a throw completion. 이것은 이름이 name인 식별자의 현재 바인딩 값을 value로 바꾸려 시도한다. 바인딩이 불변 바인딩이고 strict이 true이면, TypeError가 던져진다. 이름이 name인 바인딩은 보통 이미 존재하지만, 존재하지 않거나 현재 writable하지 않은 경우 오류 처리는 strict에 의해 결정된다. It performs the following steps when called:
declarativeRecord를 envRec.[[DeclarativeRecord]]라고 하자.
The GetBindingValue concrete method of a Global Environment RecordenvRec takes arguments name (a String) and strict (a Boolean) and returns either a normal completion containing an ECMAScript language value or a throw completion. 이것은 이름이 name인 바인딩된 식별자의 값을 반환한다. 바인딩이 초기화되지 않은 바인딩이면, ReferenceError 예외를 던진다. 이름이 name인 바인딩은 보통 이미 존재하지만, 존재하지 않거나 현재 writable하지 않은 경우 오류 처리는 strict에 의해 결정된다. It performs the following steps when called:
declarativeRecord를 envRec.[[DeclarativeRecord]]라고 하자.
The WithBaseObject concrete method of a Global Environment RecordenvRec takes no arguments and returns undefined. It performs the following steps when called:
undefined를 반환한다.
9.1.1.4.12 HasLexicalDeclaration ( envRec, name )
The abstract operation HasLexicalDeclaration takes arguments envRec (a Global Environment Record) and name (a String) and returns a Boolean. 이것은 인수 식별자가 LexicalDeclaration이나 ClassDeclaration과 같은 lexical declaration을 사용해 envRec 안에 생성된 바인딩을 가지는지 결정한다. It performs the following steps when called:
declarativeRecord를 envRec.[[DeclarativeRecord]]라고 하자.
9.1.1.4.13 HasRestrictedGlobalProperty ( envRec, name )
The abstract operation HasRestrictedGlobalProperty takes arguments envRec (a Global Environment Record) and name (a String) and returns either a normal completion containing a Boolean or a throw completion. 이것은 인수 식별자가 전역 lexical 바인딩에 의해 가려져서는 안 되는 전역 객체의 프로퍼티 이름인지 결정한다. It performs the following steps when called:
objectRecord를 envRec.[[ObjectRecord]]라고 하자.
globalObject를 objectRecord.[[BindingObject]]라고 하자.
existingProp를 ? globalObject.[[GetOwnProperty]](name)라고 하자.
전역 객체에는 var 또는 함수 선언을 사용해 선언된 것이 아니라 직접 생성된 프로퍼티가 존재할 수 있다. 전역 lexical 바인딩은 전역 객체의 non-configurable 프로퍼티와 같은 이름으로 생성될 수 없다. 전역 프로퍼티 "undefined"는 그러한 프로퍼티의 예이다.
9.1.1.4.14 CanDeclareGlobalVar ( envRec, name )
The abstract operation CanDeclareGlobalVar takes arguments envRec (a Global Environment Record) and name (a String) and returns either a normal completion containing a Boolean or a throw completion. 이것은 동일한 인수 name에 대해 대응하는 CreateGlobalVarBinding 호출이 수행된다면 성공할지를 결정한다. 중복 var 선언과 기존 전역 객체 프로퍼티에 대한 var 선언은 허용된다. It performs the following steps when called:
objectRecord를 envRec.[[ObjectRecord]]라고 하자.
globalObject를 objectRecord.[[BindingObject]]라고 하자.
The abstract operation CreateGlobalVarBinding takes arguments envRec (a Global Environment Record), name (a String), and deletable (a Boolean) and returns either a normal completion containing unused or a throw completion. 이것은 연관된 Object Environment Record 안에 가변 바인딩을 생성하고 초기화한다. 바인딩이 이미 존재하면, 그것을 재사용하며 이미 초기화된 것으로 간주한다. It performs the following steps when called:
objectRecord를 envRec.[[ObjectRecord]]라고 하자.
globalObject를 objectRecord.[[BindingObject]]라고 하자.
The abstract operation CreateGlobalFunctionBinding takes arguments envRec (a Global Environment Record), name (a String), value (an ECMAScript function object), and deletable (a Boolean) and returns either a normal completion containing unused or a throw completion. 이것은 연관된 Object Environment Record 안에 가변 바인딩을 생성하고 초기화한다. 바인딩이 이미 존재하면, 그것을 교체한다. It performs the following steps when called:
objectRecord를 envRec.[[ObjectRecord]]라고 하자.
globalObject를 objectRecord.[[BindingObject]]라고 하자.
existingProp를 ? globalObject.[[GetOwnProperty]](name)라고 하자.
전역 함수 선언은 항상 전역 객체의 own 프로퍼티로 표현된다. 가능하다면 기존 own 프로퍼티는 표준 속성 값 집합을 가지도록 재구성된다. 단계 7는 InitializeBinding 구체 메서드를 호출했을 때 하는 일과 동등하며, globalObject가 Proxy라면 같은 순서의 Proxy trap 호출을 발생시킨다.
9.1.1.5 Module Environment Record
Module Environment Record는 ECMAScript Module의 바깥 스코프를 나타내는 데 사용되는 Declarative Environment Record이다. 일반적인 가변 및 불변 바인딩에 더해, Module Environment Record는 불변 import 바인딩도 제공하는데, 이것은 다른 Environment Record에 존재하는 대상 바인딩에 대한 간접 접근을 제공하는 바인딩이다.
The GetBindingValue concrete method of a Module Environment RecordenvRec takes arguments name (a String) and strict (a Boolean) and returns either a normal completion containing an ECMAScript language value or a throw completion. 이것은 이름이 name인 바인딩된 식별자의 값을 반환한다. 그러나 바인딩이 간접 바인딩이면, 대상 바인딩의 값을 반환한다. 바인딩이 존재하지만 초기화되지 않았다면 ReferenceError가 던져진다. It performs the following steps when called:
The abstract operation CreateImportBinding takes arguments envRec (a Module Environment Record), name (a String), targetModule (a Module Record), and targetName (a String) and returns unused. 이것은 이름 name에 대해 초기화된 새로운 불변 간접 바인딩을 생성한다. envRec 안에는 name에 대한 바인딩이 이미 존재해서는 안 된다. targetName은 targetModule의 Module Environment Record 안에 존재하는 바인딩의 이름이다. 새 바인딩 값에 대한 접근은 대상 바인딩의 바인딩된 값에 간접적으로 접근하게 된다. It performs the following steps when called:
The abstract operation GetIdentifierReference takes arguments env (an Environment Record or null), name (a String), and strict (a Boolean) and returns either a normal completion containing a Reference Record or a throw completion. It performs the following steps when called:
The abstract operation NewDeclarativeEnvironment takes argument outerEnv (an Environment Record or null) and returns a Declarative Environment Record. It performs the following steps when called:
The abstract operation NewObjectEnvironment takes arguments obj (an Object), isWithEnvironment (a Boolean), and outerEnv (an Environment Record or null) and returns an Object Environment Record. It performs the following steps when called:
The abstract operation NewFunctionEnvironment takes arguments func (an ECMAScript function object) and newTarget (an Object or undefined) and returns a Function Environment Record. It performs the following steps when called:
그렇지 않으면, env.[[ThisBindingStatus]]를 uninitialized로 설정한다.
env.[[NewTarget]]를 newTarget으로 설정한다.
env.[[OuterEnv]]를 func.[[Environment]]로 설정한다.
env를 반환한다.
9.1.2.5 NewGlobalEnvironment ( obj, thisValue )
The abstract operation NewGlobalEnvironment takes arguments obj (an Object) and thisValue (an Object) and returns a Global Environment Record. It performs the following steps when called:
The abstract operation ResolvePrivateIdentifier takes arguments privateEnv (a PrivateEnvironment Record) and identifier (a String) and returns a Private Name. It performs the following steps when called:
평가되기 전에, 모든 ECMAScript 코드는 반드시 realm과 연관되어야 한다. 개념적으로 realm은 intrinsic object들의 집합, ECMAScript 전역 환경, 그 전역 환경의 범위 안에서 로드된 모든 ECMAScript 코드, 그리고 다른 연관된 상태 및 자원으로 구성된다.
realm은 이 명세에서 Table 19에 명시된 필드를 가진 Realm Record로 표현된다:
템플릿 객체는 각 realm의 Realm Record의 [[TemplateMap]]을 사용해 별도로 canonicalize된다. 각 [[Site]] 값은 TemplateLiteral인 Parse Node이다. 연관된 [[Array]] 값은 tag 함수에 전달되는 대응 템플릿 객체이다.
Note 1
어떤 Parse Node가 도달 불가능해지면, 대응하는 [[Array]]도 역시 도달 불가능해지며, 구현이 그 쌍을 [[TemplateMap]] 리스트에서 제거하더라도 관찰 불가능하다.
The abstract operation InitializeHostDefinedRealm takes no arguments and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:
Table 6에 나열된 값으로 realmRec.[[Intrinsics]]의 필드를 설정한다. 필드 이름은 표의 “Intrinsic Name” 열에 나열된 이름들이다. 각 필드의 값은 19부터 28까지의 절에서 각 객체의 명세에 따라 완전하고 재귀적으로 프로퍼티 값이 채워진 새로운 객체 값이다. 모든 객체 프로퍼티 값은 새로 생성된 객체 값이다. 내장 함수 객체인 모든 값은, steps가 이 명세에 제공된 그 함수의 정의이고, name이 함수의 "name" 프로퍼티의 초기값이며, length가 함수의 "length" 프로퍼티의 초기값이고, slots가 함수의 명시된 internal slot 이름들의 리스트(있다면)이며, prototype이 함수의 [[Prototype]] internal slot의 명시된 값이고, async가 함수가 “async”로 설명되는 경우 true 아니면 false일 때, CreateBuiltinFunction(steps, length, name, slots, realmRec, prototype, async)를 수행함으로써 생성된다. intrinsic 및 그 프로퍼티의 생성은 아직 생성되지 않은 객체에 대한 의존성을 피할 수 있도록 순서가 정해져야 한다.
The abstract operation SetDefaultGlobalBindings takes argument realmRec (a Realm Record) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:
desc를 그 프로퍼티에 대해 명시된 속성을 포함하는, 완전히 채워진 데이터 Property Descriptor라고 하자. 19.2, 19.3, 또는 19.4에 나열된 프로퍼티들에 대해서는 [[Value]] 속성의 값이 realmRec의 대응 intrinsic object이다.
execution context는 ECMAScript 구현에 의한 코드의 런타임 평가를 추적하는 데 사용되는 명세 장치이다. 어떤 시점에도 실제로 코드를 실행 중인 execution context는 agent당 최대 하나뿐이다. 이것을 그 agent의 running execution context라고 한다. 이 명세에서 running execution context에 대한 모든 참조는 주변 agent의 running execution context를 의미한다.
execution context는 순전히 명세 메커니즘이며, ECMAScript 구현의 어떤 특정 산출물과 대응할 필요는 없다. ECMAScript 코드가 execution context에 직접 접근하거나 관찰하는 것은 불가능하다.
9.4.1 GetActiveScriptOrModule ( )
The abstract operation GetActiveScriptOrModule takes no arguments and returns a Script Record, a Module Record, or null. 이것은 running execution context를 바탕으로 현재 실행 중인 script 또는 module을 결정하는 데 사용된다. It performs the following steps when called:
The abstract operation ResolveBinding takes argument name (a String) and optional argument env (an Environment Record or undefined) and returns either a normal completion containing a Reference Record or a throw completion. 이것은 name의 바인딩을 결정하는 데 사용된다. env는 바인딩을 검색할 Environment Record를 명시적으로 제공하는 데 사용될 수 있다. It performs the following steps when called:
ResolveBinding의 결과는 항상 [[ReferencedName]] 필드가 name인 Reference Record이다.
9.4.3 GetThisEnvironment ( )
The abstract operation GetThisEnvironment takes no arguments and returns an Environment Record. 이것은 현재 키워드this의 바인딩을 제공하는 Environment Record를 찾는다. It performs the following steps when called:
단계 2의 반복은 항상 종료된다. 왜냐하면 환경 리스트는 언제나 this 바인딩을 가지는 전역 환경에서 끝나기 때문이다.
9.4.4 ResolveThisBinding ( )
The abstract operation ResolveThisBinding takes no arguments and returns either a normal completion containing an ECMAScript language value or a throw completion. 이것은 running execution context의 LexicalEnvironment를 사용해 키워드this의 바인딩을 결정한다. It performs the following steps when called:
The abstract operation GetNewTarget takes no arguments and returns an Object or undefined. 이것은 running execution context의 LexicalEnvironment를 사용해 NewTarget 값을 결정한다. It performs the following steps when called:
The abstract operation GetGlobalObject takes no arguments and returns an Object. 이것은 현재 running execution context가 사용하는 전역 객체를 반환한다. It performs the following steps when called:
The abstract operation RunSuspendedContext takes arguments context (an execution context) and completionRecord (a Completion Record) and returns either a normal completion containing either an ECMAScript language value or unused, or an abrupt completion. 이는 context를 재개하고(completionRecord를 재개 값으로 전송), 그 결과를 기다린다. It performs the following steps when called:
callerContext를 실행 중인 실행 컨텍스트라 하자.
callerContext를 일시 중단한다.
context를 실행 컨텍스트 스택에 푸시한다. 이제 context가 실행 중인 실행 컨텍스트이다.
context의 일시 중단된 평가를 재개한다. 이때 completionRecord를 그것을 일시 중단한 연산의 결과로 사용한다. 재개된 계산이 반환한 Completion Record를 result라 하자.
Assert: 이 단계에 도달했을 때, context는 이미 실행 컨텍스트 스택에서 제거되었고 callerContext가 다시 실행 중인 실행 컨텍스트이다.
JobCallback Record { [[Callback]]: callback, [[HostDefined]]: empty }를 반환한다.
웹 브라우저가 아닌 ECMAScript 호스트는 HostMakeJobCallback의 기본 구현을 사용해야 한다.
Note
이것은 callback이 결국 스케줄되고 실행되도록 책임지는 함수에 전달되는 시점에 호출된다. 예를 들어, promise.then(thenAction)은 reaction Job이 스케줄되는 시점이 아니라 Promise.prototype.then 호출 시점에 thenAction에 대해 MakeJobCallback을 호출한다.
웹 브라우저가 아닌 ECMAScript 호스트는 HostCallJobCallback의 기본 구현을 사용해야 한다.
9.5.4 HostEnqueueGenericJob ( job, realm )
The host-defined abstract operation HostEnqueueGenericJob takes arguments job (a JobAbstract Closure) and realm (a Realm Record) and returns unused. 이것은 realm.[[AgentSignifier]]로 표시되는 agent 안의 realmrealm에서 job이 미래의 어느 시점에 수행되도록 스케줄한다. 이 알고리즘과 함께 사용되는 Abstract Closure는 우선순위나 순서 같은 추가 제약 없이 스케줄되도록 의도된다.
The host-defined abstract operation HostEnqueuePromiseJob takes arguments job (a JobAbstract Closure) and realm (a Realm Record or null) and returns unused. 이것은 job이 미래의 어느 시점에 수행되도록 스케줄한다. 이 알고리즘과 함께 사용되는 Abstract Closure는 Promise 처리와 관련되거나, 또는 Promise 처리 연산과 동등한 우선순위로 스케줄되도록 의도된다.
HostEnqueuePromiseJob의 구현은 9.5의 요구 사항뿐 아니라 다음도 준수해야 한다:
realm이 null이 아니면, job이 호출될 때마다 구현은 job 호출 시점에 execution이 ECMAScript 코드를 평가할 준비가 되어 있도록 구현 정의 단계를 수행해야 한다.
HostEnqueuePromiseJob이 호출되는 시점의 GetActiveScriptOrModule()을 scriptOrModule이라 하자. realm이 null이 아니면, job이 호출될 때마다 구현은 job 호출 시점에 scriptOrModule이 active script 또는 module이 되도록 구현 정의 단계를 수행해야 한다.
Job은 그것들을 스케줄한 HostEnqueuePromiseJob 호출과 같은 순서로 실행되어야 한다.
The host-defined abstract operation HostEnqueueTimeoutJob takes arguments timeoutJob (a JobAbstract Closure), realm (a Realm Record), and milliseconds (a non-negative finite Number) and returns unused. 이것은 realm.[[AgentSignifier]]로 표시되는 agent 안의 realmrealm에서 timeoutJob이 적어도 milliseconds 밀리초 이후에 수행되도록 스케줄한다.
예를 들어, 일부 웹 브라우저는 브라우저 창의 서로 관련 없는 여러 탭 사이에서 하나의 실행 스레드를 공유한다.
에이전트의 실행 스레드가 알고리즘 단계를 실행하고 있는 동안, 그 단계들에 대해 해당 에이전트는 주변 에이전트이다. 그 단계들은 주변 에이전트를 사용하여 에이전트 내부에 보관된 명세 수준 실행 객체들, 즉 실행 중인 실행 컨텍스트, 실행 컨텍스트 스택, 그리고 에이전트 레코드의 필드들에 접근한다.
초기값은 새로운 빈 List이며, 현재 Job이 끝날 때까지 살아 있도록 유지해야 하는 객체 및/또는 심벌들의 목록을 나타낸다
[[ModuleAsyncEvaluationCount]]
an integer
초기값은 0이며, 비동기적이거나 비동기 의존성을 가진 모듈의 [[AsyncEvaluationOrder]] 필드에 고유하게 증가하는 값을 할당하는 데 사용된다.
[[LittleEndian]], [[Signifier]], [[IsLockFree1]], [[IsLockFree2]], 그리고 [[IsLockFree8]]의 값은 변경될 수 없다.
Note 2
[[IsLockFree1]], [[IsLockFree2]], 그리고 [[IsLockFree8]]의 값은 반드시 하드웨어에 의해 결정되는 것은 아니며, ECMAScript 구현마다 그리고 시간에 따라 달라질 수 있는 구현 선택을 반영할 수도 있다.
[[IsLockFree4]] 필드는 없다: 4바이트 원자적 연산은 항상 lock-free이다.
실제로, 원자적 연산이 어떤 종류의 락으로 구현된다면 그 연산은 lock-free가 아니다. Lock-free는 wait-free를 의미하지 않는다: lock-free 원자적 연산을 완료하는 데 얼마나 많은 머신 단계가 필요할지에 대한 상한은 없다.
크기 n의 원자적 접근이 lock-free라는 사실은 크기 n의 비원자적 접근의 (인지된) 원자성에 대해 아무것도 의미하지 않는다. 특히 비원자적 접근은 여전히 여러 개의 개별 메모리 접근 시퀀스로 수행될 수 있다. 자세한 내용은 ReadSharedMemory와 WriteSharedMemory를 보라.
Note 3
에이전트는 명세 메커니즘이며, ECMAScript 구현의 어떤 특정 산출물과 대응할 필요는 없다.
9.6.1 AgentSignifier ( )
The abstract operation AgentSignifier takes no arguments and returns an agent signifier. It performs the following steps when called:
일부 환경에서는 특정 에이전트가 중단될 수 있도록 하는 것이 합리적이지 않을 수 있다. 예를 들어 웹 브라우저 환경에서는 문서의 메인 이벤트 처리 스레드의 중단을 허용하지 않는 것이 합리적일 수 있지만, 워커의 이벤트 처리 스레드는 여전히 중단을 허용할 수 있다.
9.6.3 IncrementModuleAsyncEvaluationCount ( )
The abstract operation IncrementModuleAsyncEvaluationCount takes no arguments and returns a non-negative integer. It performs the following steps when called:
클러스터에 속한 에이전트들이 어떤 특정 시점에 모두 살아 있을 필요는 없다. 에이전트A가 다른 에이전트B를 생성하고, 그 후 A가 종료되며 B가 에이전트C를 생성하는 경우, A가 B와 어떤 메모리를 공유할 수 있었고 B가 C와 어떤 메모리를 공유할 수 있었다면 이 세 에이전트는 같은 클러스터에 속한다.
클러스터 내의 모든 에이전트는 각자의 에이전트 레코드에서 [[LittleEndian]] 필드에 대해 같은 값을 가져야 한다.
Note 3
에이전트 클러스터 내의 서로 다른 에이전트들이 [[LittleEndian]]의 서로 다른 값을 가지면 다중 바이트 데이터에 공유 메모리를 사용하는 것이 어려워진다.
클러스터 내의 모든 에이전트는 각자의 에이전트 레코드에서 [[IsLockFree1]] 필드에 대해 같은 값을 가져야 하며, [[IsLockFree2]] 및 [[IsLockFree8]] 필드도 마찬가지이다.
클러스터 내의 모든 에이전트는 각자의 에이전트 레코드에서 [[Signifier]] 필드에 대해 서로 다른 값을 가져야 한다.
임베딩은 에이전트의 지식이나 협조 없이 에이전트를 비활성화(전진 진행 중지)하거나 활성화(전진 진행 재개)할 수 있다. 임베딩이 그렇게 하는 경우, 클러스터 내 일부 에이전트는 활성 상태로 두면서 다른 에이전트들은 무기한 비활성화된 상태로 남겨두어서는 안 된다.
Note 4
앞선 제한의 목적은 다른 에이전트가 비활성화되었기 때문에 어떤 에이전트가 교착 상태에 빠지거나 기아 상태에 빠지는 상황을 피하는 것이다. 예를 들어, 어떤 창의 문서들과 독립된 수명을 가진 HTML 공유 워커가, 그러한 독립 문서의 전용 워커와 메모리를 공유하는 것이 허용되었고, 문서와 그 전용 워커가 전용 워커가 락을 쥔 상태에서 비활성화된다면(예를 들어 문서가 자신의 창 기록으로 밀려나는 경우), 그 후 공유 워커가 그 락을 획득하려고 하면 공유 워커는 전용 워커가 다시 활성화될 때까지, 혹은 영원히, 블록될 것이다. 그 사이 다른 창에서 공유 워커에 접근하려는 다른 워커들은 기아 상태에 빠질 것이다.
이 제한의 함의는, 임베딩 내에서 같은 suspend/wake 집합에 속하지 않는 에이전트들 사이에서는 메모리를 공유하는 것이 불가능하다는 점이다.
임베딩은 클러스터의 다른 에이전트들의 사전 지식이나 협조 없이 에이전트를 종료할 수 있다. 에이전트가 자기 자신이나 클러스터 내 다른 에이전트의 프로그램적 동작이 아니라 클러스터 외부의 힘에 의해 종료되는 경우, 임베딩은 두 가지 전략 중 하나를 선택해야 한다: 클러스터의 모든 에이전트를 종료하거나, 또는 클러스터 내 에이전트들이 조정할 수 있도록 신뢰할 수 있는 API를 제공하여 적어도 하나의 남아 있는 클러스터 구성원이 종료를 감지할 수 있게 해야 하며, 종료 데이터는 종료된 에이전트를 식별하기에 충분한 정보를 포함해야 한다.
Note 5
그러한 유형의 종료 예시는 다음과 같다: 별도 프로세스에서 실행 중인 에이전트를 운영체제나 사용자가 종료하는 경우; 또는 임베딩 자체가 다른 에이전트들과 같은 프로세스 내에서 실행 중인 에이전트를 종료하는 경우로, 에이전트별 자원 회계 결과 그 에이전트가 폭주 중이라고 나타나는 경우이다.
다음 명세 값 각각과, 그것들로부터 전이적으로 도달 가능한 값들은 정확히 하나의 에이전트 클러스터에 속한다.
에이전트의 실행 중인 실행 컨텍스트가 외부 이벤트를 동기적으로 그리고 무기한 기다릴 때, 그 에이전트는 블록된다. 이러한 의미에서 블록될 수 있는 것은 에이전트 레코드의 [[CanBlock]] 필드가 true인 에이전트뿐이다. 블록되지 않은에이전트는 블록되지 않은 에이전트이다.
에이전트는 명시적으로 블로킹을 제공하는 API를 통해서만 다른 에이전트를 블록되게 할 수 있다.
Note
이것은 메모리 모델의 liveness 보장과 함께, 모든 seq-cst 쓰기가 결국 모든 에이전트에서 관찰 가능해짐을 보장한다.
9.9 WeakRef 및 FinalizationRegistry 대상의 처리 모델
9.9.1 목표
이 명세는 어떤 객체나 심벌이 가비지 컬렉션될 것이라는 어떠한 보장도 하지 않는다. 살아 있지 않은 객체나 심벌은 오랜 시간이 지난 뒤에 해제될 수도 있고, 아예 해제되지 않을 수도 있다. 이러한 이유로, 이 명세는 가비지 컬렉션에 의해 유발되는 동작을 설명할 때 "may"라는 용어를 사용한다.
WeakRef.prototype.deref가 호출되면, referent는(undefined가 반환되지 않는다면) 이후의 동기적 접근도 같은 값을 반환하도록 살아 있게 유지된다. 이 목록은 ClearKeptObjects추상 연산을 사용하여 동기 작업이 끝날 때 재설정된다.
일부 ECMAScript 구현은 ECMAScript가 유휴 상태일 때를 포함해 백그라운드에서 실행되는 가비지 컬렉터 구현을 포함한다. 호스트 환경이 CleanupFinalizationRegistry를 스케줄할 수 있게 하면, finalizer 작업을 실행하기 위해 ECMAScript 실행을 재개할 수 있고, 이로 인해 held value를 해제하여 전체 메모리 사용량을 줄일 수 있다.
9.9.2 Liveness
어떤 객체 및/또는 심벌들의 집합 objectSet에 대해, objectSet에 관한 가정적 WeakRef-무시 실행이란, referent가 objectSet의 원소인 WeakRef의 추상 연산WeakRefDeref가 항상 undefined를 반환하는 실행을 말한다.
Note 1
WeakRef-무시성과 liveness는 함께 두 가지 개념을 포착한다. 첫째, WeakRef 자체는 referent를 살아 있게 유지하지 않는다는 점이다. 둘째, liveness의 순환이 어떤 값이 살아 있음을 의미하지는 않는다는 점이다. 구체적으로 말하면, v의 liveness를 결정하는 일이 WeakRef referent인 r의 liveness를 결정하는 데 의존한다면, r의 liveness는 v의 liveness를 가정할 수 없는데, 이는 순환 논법이 되기 때문이다.
Note 2
WeakRef-무시성은 순환을 고려하기 위해 개별 값이 아니라 객체나 심벌의 집합에 대해 정의된다. 만약 개별 값에 대해 정의된다면, 순환 안에 있는 WeakRef referent는 그 정체성이 오직 순환 안의 다른 WeakRef referent를 통해서만 관찰되더라도 살아 있는 것으로 간주될 것이다.
Note 3
구어적으로, 어떤 개별 객체 또는 심벌을 포함하는 모든 집합이 live라면 그 객체 또는 심벌은 live하다고 말한다.
평가 중 어느 시점에서든, 객체 및/또는 심벌들의 집합 objectSet은 다음 조건 중 하나라도 만족하면 live하다고 간주된다:
objectSet의 어떤 원소든 임의의 에이전트의 [[KeptAlive]]List에 포함된다.
objectSet에 관해 유효한 미래의 가정적 WeakRef-무시 실행이 존재하며, 그 실행이 objectSet 안의 어떤 값의 정체성을 관찰한다.
Note 4
위의 두 번째 조건은 어떤 값의 정체성이 비-WeakRef 수단으로 관찰 가능하다면 그 값이 live하다는 직관을 포착하려는 것이다. 값의 정체성은 strict equality 비교를 관찰하거나, 그 값이 Map의 key로 사용되는 것을 관찰함으로써 관찰될 수 있다.
Note 5
객체나 심벌이 어떤 필드, 내부 슬롯, 또는 프로퍼티 안에 존재한다고 해서 그 값이 live하다는 뜻은 아니다. 예를 들어 해당 값이 결코 프로그램으로 다시 전달되지 않는다면, 그 값은 관찰될 수 없다.
이는 WeakMap의 key, WeakSet의 member, 그리고 FinalizationRegistry Cell record의 [[WeakRefTarget]] 및 [[UnregisterToken]] 필드의 경우에 해당한다.
위 정의는, WeakMap의 key가 live하지 않다면 그에 대응하는 value도 반드시 live한 것은 아니라는 점을 함의한다.
Note 6
Liveness는 엔진이 비워서는 안 되는 WeakRef를 보장하는 하한이다. 여기서 정의된 liveness는 결정 불가능하다. 실제로 엔진은 도달 가능성과 같은 보수적 근사를 사용한다. 구현에는 상당한 재량이 기대된다.
9.9.3 실행
어느 시점에서든, 객체 및/또는 심벌들의 집합 objectSet이 live하지 않다면, ECMAScript 구현은 다음 단계를 원자적으로 수행할 수 있다:
objectSet의 각 원소 value에 대해, 다음을 수행한다
ref.[[WeakRefTarget]]이 value인 각 WeakRefref에 대해, 다음을 수행한다
map.[[WeakMapData]]가 r.[[Key]]가 value인 Recordr을 포함하는 각 WeakMap map에 대해, 다음을 수행한다
r.[[Key]]를 empty로 설정한다.
r.[[Value]]를 empty로 설정한다.
set.[[WeakSetData]]가 value를 포함하는 각 WeakSet set에 대해, 다음을 수행한다.
set.[[WeakSetData]]에서 값이 value인 원소를 값이 empty인 원소로 교체한다.
Note 1
liveness의 정의와 함께, 이 절은 구현이 WeakRef와 관련하여 적용할 수 있는 최적화를 규정한다.
객체의 정체성을 관찰하지 않고도 객체에 접근하는 것은 가능하다. 정체성이 관찰되지 않는 비탈출 객체의 프로퍼티에 대한 dead variable elimination이나 scalar replacement 같은 최적화는 허용된다. 따라서 이러한 최적화는 그러한 객체를 가리키는 WeakRef를 관찰 가능하게 비우는 것도 허용된다.
반면에 어떤 객체의 정체성이 관찰 가능하고, 그 객체가 WeakRef의 [[WeakRefTarget]] 내부 슬롯 안에 있다면, WeakRef를 관찰 가능하게 비우는 rematerialization 같은 최적화는 금지된다.
구현은 live하지 않은 객체나 심벌의 최대 집합에 대해 WeakRef를 비울 의무가 없다.
구현이 WeakRef를 비울 live하지 않은 집합 objectSet을 선택한다면, 이 정의는 objectSet 안의 모든 값에 대한 WeakRef를 동시에 비워야 함을 요구한다. 즉, 구현이 어떤 값 v를 가리키는 WeakRef를 비우면서, 비워지지 않을 경우 v의 값을 관찰하는 실행이 가능해질 수 있는 다른 WeakRef는 비우지 않는 것은 적합하지 않다.
The host-defined abstract operation HostEnqueueFinalizationRegistryCleanupJob takes argument finalizationRegistry (a FinalizationRegistry) and returns unused.
finalizationRegistry를 캡처하고, 호출될 때 다음 단계를 수행하는 매개변수 없는 새로운 JobAbstract Closure를 cleanupJob이라고 하자:
HostEnqueueFinalizationRegistryCleanupJob의 구현은 가능하다면 cleanupJob이 미래의 어느 시점에 수행되도록 스케줄한다. 또한 9.5의 요구 사항도 준수해야 한다.
9.10 ClearKeptObjects ( )
The abstract operation ClearKeptObjects takes no arguments and returns unused. ECMAScript 구현은 동기적인 ECMAScript 실행 시퀀스가 완료될 때 ClearKeptObjects를 호출할 것으로 기대된다. It performs the following steps when called:
The abstract operation CleanupFinalizationRegistry takes argument finalizationRegistry (a FinalizationRegistry) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:
Assert: finalizationRegistry는 [[Cells]] 및 [[CleanupCallback]] 내부 슬롯을 가진다.
callback을 finalizationRegistry.[[CleanupCallback]]이라고 하자.
finalizationRegistry.[[Cells]]가 cell.[[WeakRefTarget]]이 empty인 Recordcell을 포함하는 동안, 구현은 다음 단계를 수행할 수 있다:
The abstract operation CanBeHeldWeakly takes argument v (an ECMAScript language value) and returns a Boolean. 이것은 v가 약한 참조로 사용되기에 적합한 경우에만 true를 반환한다. 약한 참조로 사용되기에 적합한 값만이 WeakMap의 키, WeakSet의 원소, WeakRef의 대상, 또는 FinalizationRegistry의 대상들 중 하나가 될 수 있다. It performs the following steps when called:
언어적 동일성이 없는 언어 값은 사전 참조 없이도 나타날 수 있으며, 약한 참조로 사용되기에 부적합하다. Symbol.for에 의해 생성된 Symbol 값은 다른 Symbol 값과 달리 언어적 동일성을 가지지 않으며, 약한 참조로 사용되기에 부적합하다. well-known symbol은 수집되지 않을 가능성이 높지만, 개수가 제한되어 있어 다양한 구현 접근법으로 관리 가능하므로 여전히 약한 참조로 사용되기에 적합한 것으로 취급된다. 그러나 live한 WeakMap 안에서 well-known symbol에 연관된 어떤 값이든 수집되지 않을 가능성이 높으며, 구현에서 메모리 자원을 “누수”시킬 수 있다.