role of parentheses in javascript - javascript

I'd like to know the difference between the following and the role of the parentheses:
foo.bar.replace(a,b)
and
(foo.bar).replace(a,b)
do the parentheses require the contained expression to be evaluated first before moving on to the replace method? I have seen this in code I am maintaining and am curious as to why it would be neccessary? E.G.
location.hash.replace(a,b)
and
(location.hash).replace(a,b)

It is not required in your examples.
The idea is indeed that the block inside the parenthesis must be evaluated before continuing..
It is needed in cases like
(new Date()).getMilliseconds()
(not really needed in this case as noted by #Teemu)
In general use this syntax to avoid using a temporary variable..
var result = 5.3 + 2.9;
console.log( result.toFixed(1) );
can become
console.log( (5.3 +2.9).toFixed(1) );
If you were to use 5.3 + 2.9.toFixed(1) the toFixed(1) would get applied to 2.9 only, return a string and then concatenate it with 5.3 The result would be 5.32.9

Related

Difference between interpolation and concatenation in JavaScript?

The language and library I'm using is JS and AngularJS. Am I right in assuming that "interpolation" and "concatenation" both means "combination of strings and variables"?
But "interpolation" is used when you're using the double curly brackets in AngularJS. And "concatenation" is used when you're using pure JS?
Or is there another diference that I missed?
EDIT:
Is this interpolation or concatenation (I don't just put strings together but an a variable is resolved here)?
var test1 = "Hello";
var number = 2 + 3;
console.log(test1 + " " + number);
Hmm.... I guess whenever I use AngularJS library to combine some expression, then it's interpolation, right?
In Angular js interpolation helps in getting model render on the view. Where as concatenation is to allow the strings to be join together with '+' it may or may not include interpolation .
Example:-
{{}} --> interpolation
It allows your model to bind in view:-
Model:- $scope.name="rachit";
View:- <div>{{name}}</div>
result in View after rendering :- <div>rachit</div>
'+'-->concatenation
It allows to concat the values either in view or in controller or even inside interpolation.
Controller:-
$scope.name="rachit"+"gulati";
View
<div>{{name+name}}</div> //Here interpolation also comes into picture.
result:-"<div>rachitgualtirachitgualti</div>"
UPDATE 1:-
EDIT: Is this interpolation or concatenation (I don't just put strings
together but an a variable is resolved here)?
var test1 = "Hello";
var number = 2 + 3;
console.log(test1 + " " + number);
It is simple concatenation in javascript here angular is not come into picture.
UPDATE 2:-
Hmm.... I guess whenever I use AngularJS library to combine some
expression, then it's interpolation, right?
Concatenation is general term for every programming to concat two strings together.Where as in angualr js interpolation is done by {{}} with the help of $interpolation service.
Interpolation
Interpolation does mean that you want to get the code from the angular scope and show it on html page like suppose we have {{somevariable}} In this eg. it will evaluate the function in angular scope using $interpolation service.
Concatenation
It is used when you want to bind to two strings, It could be do it inside interpolation {{}} directive like {{someVariable + ' test'}} it will concate variable with test result would be someVariable test
Interpolation basically means that an expression gets resolved and concatenation is when you put a string together.

Why these unambiguous expressions are different in JavaScript?

doing some JavaScript learning and playing around with the syntax. In JavaScript semicolons are optional. It is recommended to use them, but it seems the specification does not impose them in some cases.
In particular it is said that when there is no ambiguity, then it does not make a difference whether you use them or not.
I found this example (an exercise from a blog I googled), but no explanation. I think the semicolon should not make a difference here, but it does. I don't see an ambiguity here, why is it supposed to be different. I tried to play around with some examples, it really seems different. Can't wrap my head around that :-(
var y = x + f
(a+b).toString()
and
var y = x + f;
(a+b).toString();
Would be cool if some guru could shed light on this one.
The f followed by whitespace and a ( can be interpreted as a function call. Placing a semicolon will prevent this.
The ECMAScript Standard Specification mentions the rules of Automatic Semicolon Insertion in section 11.9.1, and the second rule described there is what we need to read:
When, as the Script or Module is parsed from left to right, the end of the input stream of tokens is encountered and the parser is unable to parse the input token stream as a single complete ECMAScript Script or Module, then a semicolon is automatically inserted at the end of the input stream. emphasis mine
So there we go. In over-simplified layman language, the semi-colon is inserted if continuation of parsing doesn't give us valid code.
In your case, if we continue parsing the code, we do get valid ECMAScript code as follows: (since JavaScript isn't white-space sensitive)
var y = x + f(a+b)...
Thus, a semicolon will not be inserted.
Exceptions to this are described in the third rule (like return and yield keyword usage), but they don't apply in your code.
Whitespace in JavaScript (including line breaks) are not syntaxical. So in the above, with a little bit of rearranging the difference should become clear.
Is this:
var y = x + f(a+b).toString()
The same as this:
var y = x + f;
(a+b).toString();
Nope. In the first example, f being called as though it is a function with the variable a+b being passes as a parameter of that function.
NOTE
There is one case I'm aware of where the above isn't exactly true; return statements.
A linebreak character does act in a syntaxical way for return statements, so this:
return {
tomatoes: 'are yummy'
}
would return an object with the property tomatoes, whereas this:
return
{
tomatoes: 'are yummy'
}
would return undefined

Sweet.js macro that calls a method

I'm trying to write a sweet.js macro which needs to generate method call syntax, obj.method(), but the method is passed in to the macro as a literal expression. For example:
mcall(obj, toString().length);
// becomes
obj.toString().length;
I've got something that's close:
macro mcall {
rule { ($o, $m:expr) } => { $o.$m }
}
mcall(obj, toString().length);
However, this apparently expands to this:
obj . ( toString ( ) . length );
Where are these extra parentheses coming from, and how do I get rid of them? Should I be using case rules and #{}? I tried permutations of that but still couldn't succeed at generating a method call without extra parentheses.
So currently in sweet.js tokens bound to an :expr pattern variable get wrapped in parens to help with getting precedence to work correctly. This is kind of a hack and will get fixed soon (some more discussion here: https://github.com/mozilla/sweet.js/issues/314).
The simple solution for your example is to just not use :expr since you don't really need it:
macro mcall {
rule { ($o, $m ...) } => { $o.$m ... }
}
Side note: using :expr is technically wrong here since the RHS of a . is not allowed to be an unrestricted expression (eg 2+4 matches $m:expr but obj.2+4 is a syntax error).

Translating conditional statements in string format to actual logic

I have a good knowledge of real time graphics programming and web development, and I've started a project that requires me to take a user-created conditional string and actually use those conditions in code. This is an entirely new kind of programming problem for me.
I've tried a few experiments using loops and slicing up the conditional string...but I feel like I am missing some kind of technique that would make this more efficient and straightforward. I have a feeling regular expressions may be useful here, but perhaps not.
Here is an example string:
"IF#VAR#>=2AND$VAR2$==1OR#VAR3#<=3"
The values for those actual variables will come from an array of objects. Also, the different marker symbols around the variables denote different object arrays where the actual value can be found (variable name is an index).
I have complete control over how the conditional string is formatted (adding symbols around IF/ELSE/ELSEIF AND/OR
well as special symbols around the different operands) so my options are fairly open. How would you approach such a programming problem?
The problem you're facing is called parsing and there are numerous solutions to it. First, you can write your own "interpreter" for your mini-language, including lexer (which splits the string into tokens), parser (which builds a tree structure from a stream of tokens) and executor, which walks the tree and computes the final value. Or you can use a parser generator like PEG and have the whole thing built for you automatically - you just provide the rules of your language. Finally, you can utilize javascript built-in parser/evaluator eval. This is by far the simplest option, but eval only understands javascript syntax - so you'll have to translate your language to javascript before eval'ing it. And since eval can run arbitrary code, it's not for use in untrusted environments.
Here's an example on how to use eval with your sample input:
expr = "#VAR#>=2AND$VAR2$==1OR#VAR3#<=3"
vars = {
"#": {"VAR":5},
"$": {"VAR2":1},
"#": {"VAR3":7}
}
expr = expr.replace(/([##$])(\w+)(\1)/g, function($0, $1, $2) {
return "vars['" + $1 + "']." + $2;
}).replace(/OR/g, "||").replace(/AND/g, "&&")
result = eval(expr) // returns true

Good resources for extreme minified JavaScript (js1k-style)

As I'm sure most of the JavaScripters out there are aware, there's a new, Christmas-themed js1k. I'm planning on entering this time, but I have no experience producing such minified code. Does anyone know any good resources for this kind of thing?
Google Closure Compiler is a good javascript minifier.
There is a good online tool for quick use, or you can download the tool and run it as part of a web site build process.
Edit: Added a non-exhaustive list of tricks that you can use to minify JavaScript extremely, before using a minifier:
Shorten long variable names
Use shortened references to built in variables like d=document;w=window.
Set Interval
The setInterval function can take either a function or a string. Pass in a string to reduce the number of characters used: setInterval('a--;b++',10). Note that passing in a string forces an eval invokation so it will be slower than passing in a function.
Reduce Mathematical Calculations
Example a=b+b+b can be reduced to a=3*b.
Use Scientific Notation
10000 can be expressed in scientific notation as 1E4 saving 2 bytes.
Drop leading Zeroes
0.2 = .2 saves a byte
Ternery Operator
if (a > b) {
result = x;
}
else {
result = y;
}
can be expressed as result=a>b?x:y
Drop Braces
Braces are only required for blocks of more than one statement.
Operator Precedence
Rely on operator precedence rather than adding unneeded brackets which aid code readability.
Shorten Variable Assignment
Rather than function x(){a=1,b=2;...}() pass values into the function, function x(a,b){...}(1,2)
Think outside the box
Don't automatically reach for standard ways of doing things. Rather than using d.getElementById('p') to get a reference to a DOM element, could you use b.children[4] where d=document;b=body.
Original source for above list of tricks:
http://thingsinjars.com/post/293/the-quest-for-extreme-javascript-minification/
Spolto is right.
Any code minifier won't do the trick alone. You need to first optimize your code and then make some dirty manual tweaks.
In addition to Spolto's list of tricks I want to encourage the use of logical operators instead of the classical if else syntax. ex:
The following code
if(condition){
exp1;
}else{
exp2;
}
is somewhat equivalent to
condition&&exp1||exp2;
Another thing to consider might be multiple variable declaration :
var a = 1;var b = 2;var c = 1;
can be rewritten as :
var a=c=1,b=2;
Spolto is also right about the braces. You should drop them. But in addition, you should know that they can be dropped even for blocks of more expressions by writing the expressions delimited by a comma(with a leading ; of course) :
if(condition){
exp1;
exp2;
exp3;
}else{
exp4;
exp5;
}
Can be rewritten as :
if(condition)exp1,exp2,exp3;
else exp4,exp5;
Although it's not much (it saves you only 1 character/block for those who are counting), it might come in handy. (By the way, the latest Google Closure Compiler does this trick too).
Another trick worth mentioning is the controversial with functionality.
If you care more about the size, then you should use this because it might reduce code size.
For example, let's consider this object method:
object.method=function(){
this.a=this.b;
this.c++;
this.d(this.e);
}
This can be rewritten as :
object.method=function(){
with(this){
a=b;
c++;
d(e);
}
}
which is in most cases signifficantly smaller.
Something that most code packers & minifiers do not do is replacing large repeating tokens in the code with smaller ones. This is a nasty hack that also requires the use of eval, but since we're in it for the space, I don't think that should be a problem. Let's say you have this code :
a=function(){/*code here*/};
b=function(){/*code here*/};
c=function(){/*code here*/};
/*...*/
z=function(){/*code here*/};
This code has many "function" keywords repeating. What if you could replace them with a single(unused) character and then evaluate the code?
Here's how I would do it :
eval('a=F(){/*codehere*/};b=F(){/*codehere*/};c=F(){/*codehere*/};/*...*/z=F(){/*codehere*/};'.replace(/function/g,'F'));
Of course the replaced token(s) can be anything since our code is reduced to an evaluated string (ex: we could've replaced =function(){ with F, thus saving even more characters).
Note that this technique must be used with caution, because you can easily screw up your code with multiple text replacements; moreover, you should use it only in cases where it helps (ex: if you only have 4 function tokens, replacing them with a smaller token and then evaluating the code might actually increase the code length :
var a = "eval(''.replace(/function/g,'F'))".length,
b = ('function'.length-'F'.length)*4;
alert("you should" + (a<b?"":" NOT") + " use this technique!");
In the following link you'll find surprisingly good tricks to minify js code for this competition:
http://www.claudiocc.com/javascript-golfing/
One example: (extracted from section Short-circuit operators):
if (p) p=q; // before
p=p&&q; // after
if (!p) p=q; // before
p=p||q; // after
Or the more essoteric Canvas context hash trick:
// before
a.beginPath
a.fillRect
a.lineTo
a.stroke
a.transform
a.arc
// after
for(Z in a)a[Z[0]+(Z[6]||Z[2])]=a[Z];
a.ba
a.fc
a.ln
a.sr
a.to
a.ac
And here is another resource link with amazingly good tricks: https://github.com/jed/140bytes/wiki/Byte-saving-techniques
First off all, just throwing your code into a minifier won't help you that much. You need to have the extreme small file size in mind when you write the code. So in part, you need to learn all the tricks yourself.
Also, when it comes to minifiers, UglifyJS is the new shooting star here, its output is smaller than GCC's and it's way faster too. And since it's written in pure JavaScript it should be trivial for you to find out what all the tricks are that it applies.
But in the end it all comes down to whether you can find an intelligent, small solution for something that's awsome.
Also:
Dean Edwards Packer
http://dean.edwards.name/packer/
Uglify JS
http://marijnhaverbeke.nl/uglifyjs
A friend wrote jscrush packer for js1k.
Keep in mind to keep as much code self-similar as possible.
My workflow for extreme packing is: closure (pretty print) -> hand optimizations, function similarity, other code similarity -> closure (whitespace only) -> jscrush.
This packs away about 25% of the data.
There's also packify, but I haven't tested that myself.
This is the only online version of #cowboy's packer script:
http://iwantaneff.in/packer/
Very handy for packing / minifying JS

Categories

Resources