parseInt Alternatives for parsing numerical strings - javascript

Assuming I have a numerical string:
var foo = "0";
Assume I want to parse it as a number, and increment it assigning the value to bar (just an arithmetical example), I know I could do:
var bar = parseInt(foo, 10)+1;
But I believe the above example could be simpler and more readable. Consider this example:
//alternative 1
var bar = +foo+1;
And this one:
//alternative 2
var bar = ++foo;
Both of these will also yield the same result for bar (the latter will also increment foo, but that's no problem).
My question is, by using one of these alternatives, would I be exposing my code to the same possible implementation-dependant flaws of using parseInt without specifying a radix/base?
Or are these safe to use as well?
Fiddle for testing.

From the perspective of readability and maintainability parseInt is the best choice. It clearly tells what it does and does it reliably.
Tomorrow, when a fellow developer joins the project, of after a couple of months when you yourself will be looking at your own code, or if you suddenly decide to increment by ten instead of just one, you'll be in less trouble working with parseInt.
Also, try JSLint. It's worth it.

Related

js math equation mystery

I'm new here :)
So, in javascript, I "simply" wanted to solve X in an equation:
My original formula was:
var X = (((((k/(cc**ci))-bk*)/(0.01*kg))-18)/((0.1+0.05*d1)*(280/(w+100)))-sd)
If I recall correctly, it returned some ridiculously high number...
Ok, I guess that was one problem... so, I tried this:
var X = (((((k*1.0/(cc*1.0*ci*1.0))-bk*1.0)/(0.01*kg*1.0))-18)/((0.1+0.05*d1*1.0)*(280/(w*1.0+100)))-sd*1.0)
Now it worked quite well for these simple variables:
cc=0, ci=0, bk=100, kg=100, d1=10, w=100, sd=10
BUT.. when the solution was approaching 0, it suddenly went completely crazy.
In this case, if k=126.4 the solution should be 0. However, I'm getting "7.1054273576" instead. I calculated it with different programs (even my old pocket-calculator lol), and they all say it's 0 --> so I guess my equation should be correct.
I tried k=126.5, which returns 0.119.
and k=126.3, which returns -0.119
These are correct.
So logically k=126.4 should return 0... but it doesn't. It still returns 7.1(...) instead.
I even tried replacing all the variables with the (see above) numbers:
var X = (((((126.4*1/(1*1*1*1))-100*1)/(0.01*100*1))-18)/((0.1+0.05*10*1)*(280/(100*1+100)))-10)
--> THIS STILL RETURNS TO 7.1(...), although it should be 0.
So the problem is definitely not one of my variables.
For these tests I was using an input type="number" object to review the results, if that is of any relevance...
I still can't see the problem, this seems absolutely illogical and is a complete mystery to me. Pls help!
You missed the bit at the end. X is equal to:
7.105427357601002e-15
^
Scientific Notation!
Note the e-15 at the end. That means, in decimal notation, it's
0.000000000000007105427357601002
Or in other words, very close to 0, as far as most uses are concerned. The difference between it and 0 likely comes about by rounding.
The problem was indeed an e-15 at the end. So if anybody else is stumbling across this page they can stop wondering.
A very simple solution: Just use Math.round() in this case to reduce the number of integers behind the comma, so that "e" doesn't get used to describe the number.

Why is String.replace() with lambda slower than a while-loop repeatedly calling RegExp.exec()?

One problem:
I want to process a string (str) so that any parenthesised digits (matched by rgx) are replaced by values taken from the appropriate place in an array (sub):
var rgx = /\((\d+)\)/,
str = "this (0) a (1) sentence",
sub = [
"is",
"test"
],
result;
The result, given the variables declared above, should be 'this is a test sentence'.
Two solutions:
This works:
var mch,
parsed = '',
remainder = str;
while (mch = rgx.exec(remainder)) { // Not JSLint approved.
parsed += remainder.substring(0, mch.index) + sub[mch[1]];
remainder = remainder.substring(mch.index + mch[0].length);
}
result = (parsed) ? parsed + remainder : str;
But I thought the following code would be faster. It has fewer variables, is much more concise, and uses an anonymous function expression (or lambda):
result = str.replace(rgx, function() {
return sub[arguments[1]];
});
This works too, but I was wrong about the speed; in Chrome it's surprisingly (~50%, last time I checked) slower!
...
Three questions:
Why does this process appear to be slower in Chrome and (for example) faster in Firefox?
Is there a chance that the replace() method will be faster compared to the while() loop given a bigger string or array? If not, what are its benefits outside Code Golf?
Is there a way optimise this process, making it both more efficient and as fuss-free as the functional second approach?
I'd welcome any insights into what's going on behind these processes.
...
[Fo(u)r the record: I'm happy to be called out on my uses of the words 'lambda' and/or 'functional'. I'm still learning about the concepts, so don't assume I know exactly what I'm talking about and feel free to correct me if I'm misapplying the terms here.]
Why does this process appear to be slower in Chrome and (for example) faster in Firefox?
Because it has to call a (non-native) function, which is costly. Firefox's engine might be able to optimize that away by recognizing and inlining the lookup.
Is there a chance that the replace() method will be faster compared to the while() loop given a bigger string or array?
Yes, it has to do less string concatenation and assignments, and - as you said - less variables to initialize. Yet you can only test it to prove my assumptions (and also have a look at http://jsperf.com/match-and-substitute/4 for other snippets - you for example can see Opera optimizing the lambda-replace2 which does not use arguments).
If not, what are its benefits outside Code Golf?
I don't think code golf is the right term. Software quality is about readabilty and comprehensibility, in whose terms the conciseness and elegance (which is subjective though) of the functional code are the reasons to use this approach (actually I've never seen a replace with exec, substring and re-concatenation).
Is there a way optimise this process, making it both more efficient and as fuss-free as the functional second approach?
You don't need that remainder variable. The rgx has a lastIndex property which will automatically advance the match through str.
Your while loop with exec() is slightly slower than it should be, since you are doing extra work (substring) as you use exec() on a non-global regex. If you need to loop through all matches, you should use a while loop on a global regex (g flag enabled); this way, you avoid doing extra work trimming the processed part of the string.
var rgR = /\((\d+)\)/g;
var mch,
result = '',
lastAppend = 0;
while ((mch = rgR.exec(str)) !== null) {
result += str.substring(lastAppend, mch.index) + sub[mch[1]];
lastAppend = rgR.lastIndex;
}
result += str.substring(lastAppend);
This factor doesn't disturb the performance disparity between different browser, though.
It seems the performance difference comes from the implementation of the browser. Due to the unfamiliarity with the implementation, I cannot answer where the difference comes from.
In terms of power, exec() and replace() have the same power. This includes the cases where you don't use the returned value from replace(). Example 1. Example 2.
replace() method is more readable (the intention is clearer) than a while loop with exec() if you are using the value returned by the function (i.e. you are doing real replacement in the anonymous function). You also don't have to reconstruct the replaced string yourself. This is where replace is preferred over exec(). (I hope this answers the second part of question 2).
I would imagine exec() to be used for the purposes other than replacement (except for very special cases such as this). Replacement, if possible, should be done with replace().
Optimization is only necessary, if performance degrades badly on actual input. I don't have any optimization to show, since the 2 only possible options are already analyzed, with contradicting performance between 2 different browser. This may change in the future, but for now, you can choose the one that has better worst-performance-across-browser to work with.

Which three-values would you choose for a "javascript enum"?

In JavaScript, I'm building something like tic-tac-toe (but more complex). Any given field can have three values: a black piece, a white piece or nothing. What would you use to represent these values? Considering you're gonna be passing around about 300+ at a time.
I was first thinking of 'B', 'W' and 'N'. Then I thought of 0, 1 and 2 and now I'm thinking about true, false and null. Which is the better option as far as JavaScript is concerned? Faster? More idiomatic?
It is not going to make a speed difference.
Personally, I'd go with 0,1,2.
In general, I'd avoid making a difference between undefined, null and false. That will just result in some mistakes in a conditional somewhere. In your case, undefined seems a pretty poor choice anyway, because the contents of the field are not undefined/unknown, it is well-defined to be empty.
As Thilo points out you'd want to avoid having multiple values that can make the statement if(position) evaluate position as true. I'd probably go with using null as the empty value, though, as it seems to make more sense to me.
For the other values, I'd definitely go with something that it's hard to mix up. Strings aren't great, because you're going to wind up using B instead of W somewhere along the line and get annoying errors, so 1 and 2 probably aren't bad options.
Another option, though, is to make your own "enum" for the purposes - just have var black = new Object() and var white = new Object() and use those. That way it's a bit more clear what you're referring to than just 1 and 2. Much of a muchness, though.

Why is there a need for javascript coding conventions?

Suppose I have to write a javascript function:
function(){
var a=1;
var sum=1;
for(var i=0;i<6;i++){
sum=sum+a+1;
}
console.log(sum);
}
Someone recommended me to write this function like this:
function () {
var a = 1;
var sum = 1;
for (var i = 0; i < 6; i++) {
var sum = sum + a +1;
}
console.log(sum);
}
With more blank space, I know this rule, but I don't how it works, or what can I benefit from it?
It is a matter of opinion what good style is, but in a general sense picking some style and consistently following it throughout your code makes it easier to read (both for other people and for you when you come back to it later).
In my experience most people find code easier to read with the extra spaces as shown in your second example.
I don't like putting a space between function and (). Or, where there is a function name I don't put a space between the name and the parentheses: function someName().
Note also that with modern code editors that have syntax highlighting (like Stack Overflow does) it is much easier than it used to be to read code that doesn't have spaces. Compare the following two:
for(var i=0;i<6;i++)
for(var i=0;i<6;i++)
Reading and editing the latter, all in black and white, really annoys me, but I don't mind the coloured version anywhere near as much. I still prefer it with the extra spaces though.
I'd make some other changes in your function:
function() {
var a = 1,
sum = 1,
i;
for(i = 0; i < 6; i++){
sum += a + 1;
}
console.log(sum);
}
The benefit of coding style is enhanced readability. It does not really matter what style you decide to stick to, as long as you DO stick with a uniform style, and can agree with your coworkers on its readability, which is not always easy.
These coding conventions are for humans, they increase readability. Suppose I have written an expression like this:
x=(a*b/2)+m-n+c*(d/e);
It looks clumsy and difficult to read. It would have been easier to understand if we had used spaces around operators like this:
x = (a * b / 2) + m - n + c * (d / e);
Again using blank line increases readability by denoting sections. For example:
function foo() {
var a;
var b;
// a blank line here to specify the end of variable declarations
if (some_cond) {
} else if (another_cond) {
}
// another blank line to specify end of some logic
//more codes here;
}
If you do not follow these guidelines and all team members do not agree in some convention then it will be very difficult to maintain a big project for long time.
Finally note that, the conventions are not for compilers, they are for humans. That's why it is called coding guidelines, not language syntax.
May be you should read more about javascript closure, and you can follow "Google Javascript Style Guide".
Following some uniform style guidelines when coding makes code easier to read and helps you writing beautiful code, and others understanding (and loving!) your code.
For sure there are loads of resources on the net (just by googling for a while you get some javascript guides or guidelines), but this one is quite easy, simple and complete:
http://javascript.crockford.com/code.html
It's not a rule. It's just coding convention style. You don't need to follow if you don't want. But this style can make your code more readable, easier to maintain, and cleaner. To me, I prefer to have space rather than narrow letters. Again, it's not a rule.
Coding style is always very personal; one person likes condensed code so that they can see as much as possible on one screen, another needs the opening and closing braces on a separate line, etc.
When only coding for yourself, you should choose whatever is best for you. But when you start working in teams and others have to maintain your code and visa versa, it becomes important to agree on one coding style ... and this can be hard.
I've sat in coding style discussions and they're very uncomfortable, because you're giving up some of your personal preferences albeit for the greater good. After a brief moment of discomfort you will get used to it ;-)
The second version isn't equivalent to the first, as it declares an inner 'sum' variable, unless Javascript doesn't do what it says on the tin with that.
The extra blank lines don't contribute anything much IMHO, but I probably wouldn't die in a ditch about them. However an equally valid concern is download speed, which is made worse by the suggestion.

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