closure-compiler icon indicating copy to clipboard operation
closure-compiler copied to clipboard

`var` is not hoisted to the nearest variable scope

Open bradzacher opened this issue 9 months ago • 1 comments

input code:

function foo(arg) {
  switch(arg.type){
      case 'foo':
          var _arg_foo;
          (_arg_foo = arg.foo) === null || _arg_foo === void 0 ? void 0 : _arg_foo.foo();
          break;
      case 'bar':
          var _arg_foo1;
          (_arg_foo1 = arg.foo) === null || _arg_foo1 === void 0 ? void 0 : _arg_foo1.bar();
          break;
      case 'baz':
          var _arg_foo2;
          (_arg_foo2 = arg.foo) === null || _arg_foo2 === void 0 ? void 0 : _arg_foo2.baz();
          break;
  }
}
console.log(foo);

Note: input code is the generated by swc downlevelling optional chaining

Actual CC output:

console.log(function(a) {
  switch(a.type) {
    case "foo":
      var b;
      null === (b = a.g) || void 0 === b ? void 0 : b.g();
      break;
    case "bar":
      var c;
      null === (c = a.g) || void 0 === c ? void 0 : c.h();
      break;
    case "baz":
      var d;
      null === (d = a.g) || void 0 === d ? void 0 : d.i();
  }
});

Expected CC output:

console.log(function(a) {
  var b,c,d;
  switch(a.type) {
    case "foo":
      null === (b = a.g) || void 0 === b ? void 0 : b.g();
      break;
    case "bar":
      null === (c = a.g) || void 0 === c ? void 0 : c.h();
      break;
    case "baz":
      null === (d = a.g) || void 0 === d ? void 0 : d.i();
  }
});

CC does not hoist the vars to the nearest variable scope, even though (as I understand it) it should be runtime equivalent to do so. If it did hoist the variables then it could collapse them into a single declaration and save the additional var per variable - which would leads to +4b per variable declared within the same variable scope.

bradzacher avatar Sep 14 '23 03:09 bradzacher