Here’s an excerpt from the start the jQuery source code (1.7.1):
// Define a local copy of jQuery
var jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init( selector, context, rootjQuery );
},
// Map over jQuery in case of overwrite
_jQuery = window.jQuery,
// Map over the $ in case of overwrite
_$ = window.$,
// ...continues...
// [[Class]] -> type pairs
class2type = {};
The code is a series of variable assignments, all joined by the ma operator. As I understand the ma operator, it evaluates the expressions before and after it, and returns the value of the latter one.
As the chain of variable assignments isn’t being assigned to anything, it struck me that the code could be rewritten with semicolons in place of the mas, without changing how it operates. E.g.
// Define a local copy of jQuery
var jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init( selector, context, rootjQuery );
}; /* <----- semicolon */
// Map over jQuery in case of overwrite
_jQuery = window.jQuery; /* <----- semicolon */
// Map over the $ in case of overwrite
_$ = window.$; /* <----- semicolon */
// ...and so on.
Would the code have the same effect if rewritten with semicolons like this, or am I missing something?
If it would have the same effect, what are the style reasons for writing it with mas? (I know, for example, that Crockford doesn’t like the ma operator (see near the bottom), although I don’t know why.)
Here’s an excerpt from the start the jQuery source code (1.7.1):
// Define a local copy of jQuery
var jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init( selector, context, rootjQuery );
},
// Map over jQuery in case of overwrite
_jQuery = window.jQuery,
// Map over the $ in case of overwrite
_$ = window.$,
// ...continues...
// [[Class]] -> type pairs
class2type = {};
The code is a series of variable assignments, all joined by the ma operator. As I understand the ma operator, it evaluates the expressions before and after it, and returns the value of the latter one.
As the chain of variable assignments isn’t being assigned to anything, it struck me that the code could be rewritten with semicolons in place of the mas, without changing how it operates. E.g.
// Define a local copy of jQuery
var jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init( selector, context, rootjQuery );
}; /* <----- semicolon */
// Map over jQuery in case of overwrite
_jQuery = window.jQuery; /* <----- semicolon */
// Map over the $ in case of overwrite
_$ = window.$; /* <----- semicolon */
// ...and so on.
Would the code have the same effect if rewritten with semicolons like this, or am I missing something?
If it would have the same effect, what are the style reasons for writing it with mas? (I know, for example, that Crockford doesn’t like the ma operator (see near the bottom), although I don’t know why.)
- 2 In response to your edit, he says (emphasis mine): , (ma) Operator - Avoid the use of the ma operator except for very disciplined use in the control part of for statements. (This does not apply to the ma separator, which is used in object literals, array literals, var statements, and parameter lists.) – thirtydot Commented Feb 29, 2012 at 10:21
- 2 If you use semi-colon then need to write var for each variable, isn't it? – Brij Commented Feb 29, 2012 at 10:22
- @thirtydot: doh, gotcha, good spot. Although in the section on variable declarations, he suggests one declaration per line. (Admittedly he’s just declaring there, rather than declaring and initialising.) – Paul D. Waite Commented Feb 29, 2012 at 10:25
-
You can do one declaration per line with a single
var
and a ma operator. It would be a single statement, but spread across several lines with one variable per line. Personally I find it messy to include ments on separate lines in amongst such declarations, because it makes it harder to see where the initialvar
is, and I find it messier still to include function declarations. – nnnnnn Commented Feb 29, 2012 at 10:31 - See also stackoverflow./questions/3781406/… and stackoverflow./questions/1236206/… – Paul D. Waite Commented Feb 29, 2012 at 10:48
4 Answers
Reset to default 8No. mas separate var declarations, all using first var prefix. E.g.:
var a = 1, // local
b = 2; // local
var a = 1; // local
b = 2; // global!
In order to achieve the same effect, write it this way:
var a = 1; // local
var b = 2; // local
Personally I think this is pure bad habit deformation and influence from the main language of the creator. The code bees really hard to read and brings confusion. Especially when used in conjunction with a modular pattern where, in jQuery they declare everything on literal objects. jQuery seems to have forgotten how to declare a function constructor to instantiate a class or this simply does not apply to jQuery style.
The code will have the same effect if written with semicolon if you add a var in front of each variable:
// Define a local copy of jQuery
var jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init( selector, context, rootjQuery );
}; /* <----- semicolon */
// Map over jQuery in case of overwrite
var _jQuery = window.jQuery; /* <----- semicolon */
// Map over the $ in case of overwrite
var _$ = window.$; /* <----- semicolon */
// ...and so on.
If you omit the VAR you will create or overwrite a global variable.
I think this to ply with JSLint rules.
JSLint wants variable declarations separated by a ma rather than a semi-colon.
I'm not sure why Crockford denouces the ma operator when his tool encourages it. The message itelf reads:
Combine this with the previous 'var' statement.
I think this has several reason: one efficiency, second code tidiness and third variable scoping.
reason 1: if you specify: var var1,var2,var3;
, the engine knows you're passing a list of variables because you're preceding the list with the "var" keyword. if you would do
var var1;
var var2;
var var3;
the engine would look at the var keyword, understand it's defining variables and then look at the argument. i guess looping through a list is better than re-evaluating var every time
reason 2: For me it's much more readable to read a list separated by mas than looking at equal sign somewhere in the code.
reason 3: note that var defines the variable inside the scope of a function. if you don't preceed with var you'll be defining the variables in the global scope.
p.s - jslinters like jshint often plain if you have multiple vars inside a scope rather than one list of variables....
cheers