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);
I am confused by two things:
- Why is there a comma rather than a semi-colon between
("Test")
andtest
? - 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?
It causes an error in Chrome because your original code is invalid. What you are actually doing is assign the result of
alert("Test")
towindow.test
.alert
returnsundefined
, so when you are attempting to calltest
later on, it referencesundefined
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: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.