ES5及以上版本仍保留Activation Object(激活对象)结构吗?
Hey there! Let's tackle your question about how execution contexts work in modern JavaScript (ES5 and beyond), since the older Activation Object (AO)/Variable Object (VO) concepts have evolved quite a bit.
First, to answer your core question: No, ES5 and later versions do not use the Activation Object or Variable Object terminology or structure—those were part of the ES3 specification. The ES5 spec introduced more precise, standardized constructs to handle the same responsibilities, and ES6 built on that with additional improvements for block-scoped bindings.
What Replaced AO/VO?
The old AO/VO was replaced by two key components in the execution context:
- Lexical Environment: This is the primary structure that tracks all variable, function, and block-scoped bindings (like
let,const, andclassdeclarations). It consists of:- An Environment Record (a container for storing bindings specific to the current context—e.g., a Function Environment Record for function contexts, or a Module Environment Record for modules)
- An Outer Environment Reference that links to the parent Lexical Environment, forming the scope chain
- Variable Environment: This is a specialized Lexical Environment that specifically handles
vardeclarations and function declarations (due to their hoisting behavior). In ES6+, the Variable Environment's Environment Record is updated only forvarbindings, while the Lexical Environment tracks block-scoped bindings.
Modern Execution Context Creation Phase (ES5+)
When a new execution context is created (like when calling a function), the JS engine now performs these key steps:
- Determine the
thisbinding:- For function calls:
thisis bound based on how the function is called (e.g., default binding in non-strict mode, implicit binding for method calls, explicit binding viacall()/apply()/bind()) - For arrow functions:
thisis lexically inherited from the enclosing execution context (no dynamic binding) - For global context:
thisrefers to the global object (e.g.,windowin browsers,globalThisin modern JS)
- For function calls:
- Create the Lexical Environment:
- Initialize the Environment Record with all block-scoped bindings (
let,const,class), function declarations, and parameters - Set the Outer Environment Reference to point to the Lexical Environment of the enclosing context (building the scope chain)
- Initialize the Environment Record with all block-scoped bindings (
- Create the Variable Environment:
- Initialize it with
vardeclarations and function declarations (these are hoisted to the top of the context) - In ES6+, the Variable Environment starts as a copy of the Lexical Environment, but only updates when
varbindings are processed
- Initialize it with
Quick Comparison to the Old ES3 Steps
The old "create AO/VO" step is now split into creating the Lexical and Variable Environments, which offer more clarity and support for modern JS features like block scoping. The scope chain is still formed (via the Outer Environment Reference), and this determination is more explicitly defined in the spec.
Side note: While the terminology changed, the core idea of tracking variables, functions, and scope within an execution context remains the same—just with more precise, standardized mechanics.
内容的提问来源于stack exchange,提问作者Willem van der Veen

