Grunt Uglify produces code that browsers do not agree with

119 views Asked by At

I am new to Grunt and to grunt-contrib-uglify. I have created a test JavaScript file:

function global(window) {
  window.test = alert("Test");
  test();
})(window);

When this is uglified, it appears as

!function(a){a.test=alert("Test"),test()}(window);

jsfiddle

I am confused by two things:

  • Why is there a comma rather than a semi-colon between ("Test") and test?
  • How is it that this code actually produces the expected result?

When I run it in Chrome, an alert duly appears, but the console complains Uncaught TypeError: test is not a function. When I run it through JSHint, it reports: "Expected an assignment or function call and instead saw an expression."

Is grunt-contrib-uglify taking advantage of aspects of JavaScript that neither Chrome nor I fully understand?

1

There are 1 answers

1
Martin Wedvich On BEST ANSWER

It causes an error in Chrome because your original code is invalid. What you are actually doing is assign the result of alert("Test") to window.test. alert returns undefined, so when you are attempting to call test later on, it references undefined instead of a function. You're also missing an opening parenthesis, though that didn't cause the issue here.

It looks like what you're trying to do is create a proxied alert function that will call it with a predefined input parameter. You could do this using the bind() function, like this:

(function (window) {
    window.test = alert.bind(undefined, 'Test');
    test();
})(window);

The above should produce your expected result.

As to why it uses commas rather than semicolons, it's probably because the minified code validates to an expression (see expressions vs statements), and semicolons aren't allowed in expressions, while commas are.