Skip to content

Incorrect scope alteration of function by redeclaring as 'var' #3622

@AshleyScirra

Description

@AshleyScirra

Edit: this is probably actually just as simple as Closure not recognising "self" as an alias for "window" - see below

Tested with Closure compiler v20200614

in.js:

"use strict";

self.global1 = "foo";

{
	function foo(p) { self["external1"](p) }
	let local = self["external2"]();
	
	console.log(foo(local));
	console.log(foo(local));
}

Command:
java -jar ./closure-compiler.jar --js in.js --js_output_file out.js --compilation_level ADVANCED --language_in ECMASCRIPT_2015 --language_out ECMASCRIPT_2015 --strict_mode_input --formatting PRETTY_PRINT

This produces out.js:

'use strict';
self.a = "foo";
{
  var a = function(c) {  // <-- ERROR
    self.external1(c);
  };
  let b = self.external2();
  console.log(a(b));
  console.log(a(b));
}

Notice that:

  • self.global1 was renamed to self.a
  • function foo was redeclared as var a
  • var a outside a function overwrites the global variable, breaking code relying on self.global1

Note that some brief testing shows that inside the scope block, function foo is scoped to that block only. However a var declaration is global, even inside the scope block (presumably because it's not a function). Therefore by redeclaring a function with var inside a scope block, its scope is unintentionally expanded to global, where it trashes global variables that happen to have the same name.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions