6 ms·
How to: code JavaScript using Twitter bootstrap best practices
- DrinkWater 12y ago"The ! converts the function declaration to a function expression" .... and i closed the tab
- jbeja 12y agoSecond to this.
- Kiro 12y agoWhy?
- BonsaiDen 12y agoPrepending a ! results in the parser picking up the line as a expression instead of a statement. function foo(){}; // statement var a = function() {}; // the right side of the = is a expression, a function keyword inside a expression does also not require a name Also function statements are put into the scope before execution of the program begins, expressions on the other hand need to be evaluated. So this will work: foo(); function foo(){} While this will throw the usual `Undefined is not a function` (it does not throw foo is not defined, because the var statement gets hoisted, meaning before the code is run the compiler will move all var statements to the top of the nearest scope (i.e. function) foo(); var foo = function(){}; Now, as for why he closed the tab, first of all it is pretty clear that this is a very dumbed down explanation of the whole thing, and while there is a SO link it's not immediately clear that all operator tokens can trigger this behavior.
- rmrfrmrf 12y agoWell, when all is said in done, the statement the author makes is pretty much incorrect in every sense. `!function(){}()` is a type of immediately-invoked function expression. Even if the `!` weren't there, `function(){}` would still be a function expression (compare to `var fun = function(){};`, a function declaration). Second, `!` in JavaScript does not convert a function declaration into a function expression; it invokes the NOT operation on whatever immediately follows it. Examples: > !true; false > !false; true > !4; false > !undefined; true > !!undefined; false So, basically what this code is doing is creating a function, calling it (with `()`), and then running a NOT operation on it. I personally hate this kind of code because it's hacky and works by exploiting the interpreter. If you look at the examples of the `!` operator I gave, `!undefined` returns `true`, which is exactly what the author's code will return. Granted, the chances that you'll get bitten for using `!` over just a pair of parens is slim, you're still forcing the interpreter to waste [an incredibly small amount of] time performing useless operations just because the programmer was too lazy to type parentheses. Much better, IMO, would be `(function() {})()` or, more safely and explicitly, `(function() {}).call(this)`, which sets the function expression's context to Window even in strict mode. `foo()` is syntactic sugar for `foo.call(undefined)` in strict mode and `foo.call(window)` in non-strict mode.
- wpears 12y agoYou mixed up your definitions of function declaration and function expression. In this case, if the '!' weren't there, it would indeed be a function declaration, but with improper syntax (removing the '!' would result in a syntax error). What makes a function either an expression or declaration is simply whether the parser expects an expression or declaration in the given context. The grouping operator '()' and the NOT operator '!' both are parameterized by expressions, and so the Javascript parser treats functions passed to them as expressions. Unless located where an expression is expected, functions will default to declarations.
- rmrfrmrf 12y agoYou're right, my mistake. Brain cramp :)
- kyllo 12y agoI liked one of the responses to the SO thread: http://stackoverflow.com/questions/3755606/what-does-the-exclamation-mark-do-before-the-function http://stackoverflow.com/questions/3755606/what-does-the-exc... !function () {}() This will also return the boolean opposite of the return value of the function, in this case true, because !undefined is true. If you want the actual return value to be the result of the call, then try doing it this way: (function () {})() Why would you ever not want the actual return value of a function to be the result of calling that function?
- cocoflunchy 12y agoThere's a good discussion over here: https://github.com/airbnb/javascript/issues/44 https://github.com/airbnb/javascript/issues/44
- pjc50 12y agoOh god. Javascript's optional semicolon really has inflicted a lot of damage, hasn't it?
- mattmanser 12y agoI remember when I used to rave on at my colleagues that it was amazing back in 2005. How wrong I was.
- bshimmin 12y agoHorrible, isn't it? Baffling, quasi-random punctuation inserted to prevent random errors caused by poor design choices intended to make programmers' lives easier.
- bpicolo 12y agoYou lose the return value over (function(){})(). That's an awful recommendation.
- _harry 12y agoYup! We only recommend !function(){}(); for a module where you just need your function to run. If you rely on the return value use (function(){})(); or (function(){}()); (more on this: https://github.com/airbnb/javascript/issues/21 https://github.com/airbnb/javascript/issues/21)
- bpizzi 12y agoFYI, the blog post suggests that bootstrap is currently developped at twitter, which is not the case anymore @see http://getbootstrap.com/about/ http://getbootstrap.com/about/
- bejonster 12y agoYou're right. This has been corrected.
- usablebytes 12y agoA cleaner way to convert a function declaration into a function expression would be to use brackets (function() { //code here })(); This won't affect the return type of the statement; which in case of using ! will return boolean 'true' unless the function returns a truthy value. Plus using ! for this purpose, looks totally messy.
- dhimes 12y agoThis is what I use- in fact, I've been confused by this thread because I've never seen the '!' hack before. Even though someone called in "javascript syntax 101." I must be using good sources to learn.
- tothepixel 12y agoTo extend upon this, you can also pass in references to decrease lookup time. That's why you see people doing: (function($,window) { //code here })(jQuery,window);
- thekingshorses 12y agoThis reduces size after uglifying. (function(window, $, otherGlobal) { $ = window.jQuery; otherGlobal = window.otherGlobal; //code here })(window);
- deleted 12y ago[deleted]
- adambard 12y agoThis solves one of the problems that '!' does, but not the other. If this file is concatenated with one that looks like it would accept a function call, it will be an error, because javascript. e.g. (function(){/* stuff */}()) (function(){/* other stuff */}()) Is interpreted as: (function(){/* stuff */)())(function(){/* other stuff */}()) To correct this, you also need a semicolon. ;(function() { //code here })(); Alternatively, if you can stomach it (I can't), you can use the !.
- myhf 12y agoOh my, this isn't satire.
- edfuh 12y agoprotip: you will have a better time if you read this as satire.