Bug report
ES5
Uglify version (uglifyjs -V)
uglify-js 3.0.17
JavaScript input
test.js:
function f() {
f.g = g;
return f.g();
function f() {};
function g(){ return this }
}
The uglifyjs CLI command executed.
uglifyjs test.js -c
JavaScript incorrect output produced.
function f(){function f(){}return(f.g=function(){return this})()}
Description of the problem.
The assignment of f.g and immediate call looses the context of f when calling g. Therefore when g returns this, the later does not refer to f but to the global context.
Expected correct output.
function f(){function f(){}return(f.g=function(){return this}).call(f)}
Also correct, is the output of uglify-js 3.0.15 which is the last version that did not produce an incorrect output:
function f(){function f(){}function g(){return this}return f.g=g,f.g()}
Workaround until a fix is provided.
Do not use this in g, use f instead, this also yields a smaller output:
test-workaround.js:
function f() {
f.g = g;
return f.g();
function f() {};
function g(){ return f } // use f instead of this
}
Output:
function f(){function f(){}return f.g=function(){return f},f.g()}
Although the compressed output is still incorrect, the execution yields the right result because there is no reference to this.
@uiteoi thanks for the report - cascade is the culprit in this case:
$ cat test.js
function f() {
f.g = g;
return f.g();
function f() {};
function g(){ return this }
}
console.log(f().toString());
$ node test.js
function f() {}
```js
$ uglifyjs test.js -b bracketize -c cascade=0
function f() {
function f() {}
return f.g = function() {
return this;
}, f.g();
}
console.log(f().toString());
$ uglifyjs test.js -b bracketize -c cascade=0 | node
function f() {}
```js
$ uglifyjs test.js -b bracketize -c
function f() {
function f() {}
return (f.g = function() {
return this;
})();
}
console.log(f().toString());
$ uglifyjs test.js -b bracketize -c | node
[object global]
@alexlamsl, I am very impressed with the speed at which you fixed this with proper test cases. Also thanks for your detailed comment, it will help me in the future produce better bug reports, if I ever find anather one, using option -b and console.log() an expected output to help build test cases.