Skip to content

Instantly share code, notes, and snippets.

@awesomekling
Created June 9, 2021 21:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save awesomekling/3126e4127a67bb48aaf9d5daf5c013c5 to your computer and use it in GitHub Desktop.
Save awesomekling/3126e4127a67bb48aaf9d5daf5c013c5 to your computer and use it in GitHub Desktop.
commit 1fef53a1e8fac223db3a5211a3af4afa79331c19
Author: Andreas Kling <kling@serenityos.org>
Date: Wed Jun 9 23:21:42 2021 +0200
LibJS: Only "var" declarations go in the global object at program level
"let" and "const" go in the lexical environment.
This fixes one part of #4001 (Lexically declared variables are mixed up
with global object properties)
diff --git a/Userland/Libraries/LibJS/Interpreter.cpp b/Userland/Libraries/LibJS/Interpreter.cpp
index ebad86ede..90f458494 100644
--- a/Userland/Libraries/LibJS/Interpreter.cpp
+++ b/Userland/Libraries/LibJS/Interpreter.cpp
@@ -94,9 +94,11 @@ void Interpreter::enter_scope(const ScopeNode& scope_node, ScopeType scope_type,
HashMap<FlyString, Variable> scope_variables_with_declaration_kind;
scope_variables_with_declaration_kind.ensure_capacity(16);
+ bool is_program_node = is<Program>(scope_node);
+
for (auto& declaration : scope_node.variables()) {
for (auto& declarator : declaration.declarations()) {
- if (is<Program>(scope_node)) {
+ if (is_program_node && declaration.declaration_kind() == DeclarationKind::Var) {
declarator.target().visit(
[&](const NonnullRefPtr<Identifier>& id) {
global_object.put(id->string(), js_undefined());
diff --git a/Userland/Libraries/LibJS/Tests/global-var-let-const.js b/Userland/Libraries/LibJS/Tests/global-var-let-const.js
new file mode 100644
index 000000000..dffdf1310
--- /dev/null
+++ b/Userland/Libraries/LibJS/Tests/global-var-let-const.js
@@ -0,0 +1,21 @@
+var foo = 1;
+let bar = 2;
+const baz = 3;
+
+test("behavior of program-level var/let/const", () => {
+ expect(foo).toBe(1);
+ expect(bar).toBe(2);
+ expect(baz).toBe(3);
+ expect(globalThis.foo).toBe(1);
+ expect(globalThis.bar).toBeUndefined();
+ expect(globalThis.baz).toBeUndefined();
+ globalThis.foo = 4;
+ globalThis.bar = 5;
+ globalThis.baz = 6;
+ expect(foo).toBe(4);
+ expect(bar).toBe(2);
+ expect(baz).toBe(3);
+ expect(globalThis.foo).toBe(4);
+ expect(globalThis.bar).toBe(5);
+ expect(globalThis.baz).toBe(6);
+});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment