For my understanding the unary ! operator performs implicit type conversions, and are sometimes used for type conversion.
So basically the ! operator converts its operand to a boolean and negates it.
Now:
!!x // Same as Boolean(x)
In fact:
!!'true' === Boolean('true') // true
So I am assuming both !!x and Boolean(x) perform the same action.
I would like to know:
Do you know any caveats making my assumptions wrong?
Which way should be preferred in term of good practice?
Do you know any differences to be aware among different ECMAScript versions or Browser vendors?
Your assumptions are correct. That is exactly how it works and I'm
not aware of any special care to be taken when using this.
Speaking of good practice, you'll probably have as many people
supporting the quick 'n "dirty" !! way as there are who would
advocate using the Boolean function ; however, from my experience, it appears that
!! is way more common in library code (look at the jQuery source,
you have a lot of stuff like return !!locked;). IMHO, it is sufficiently recognizable to be used without degrading code readability.
This has all been standard for a very long time in ECMAScript ; I can't speak for old versions of Internet Explorer (before IE 8), but you can pretty much trust all modern browsers to behave the same in this case.
Useful references in the standard :
http://www.ecma-international.org/ecma-262/5.1/#sec-11.4.9
http://www.ecma-international.org/ecma-262/5.1/#sec-9.2
Do you know any caveats making my assumptions wrong?
Your assumption is correct. Both Boolean function and !! has the same functionality.
Which way should be preferred in term of good practice?
I recommend using unary operator twice because it is atleast two times faster than using Boolean with 100,000 iterations
JS fiddle link: https://jsfiddle.net/vj593auw/1/
Do you know any differences to be aware among different ECMAScript
versions or Browser vendors?
Boolean and unary operators are implemented from JavaScript 1.0, so they should be available in all browsers that supports JavaScript.
Related
I was once asked by a student why we write:
parseInt(something)
something.toLowerCase()
that is, why one has the variable as a parameter, while the other is applied to the variable.
I explained that while toLowerCase is a method of string objects, parseInt wasn’t designed that way. OK, so it’s window.parseInt, but that just makes it a method of a different object.
But it struck me as an inconsistency — why are some string or other functions not methods of their corresponding objects?
The question is why? Is there a technical reason why parseInt and other functions are not methods, or is that just a historical quirk?
In general, Javascript was designed in a hurry, so questioning each individual design decision isn't always a productive use of your time.
Having said that, for parseInt in particular, the reason is simple to explain: it accepts pretty much any arbitrary type, like:
parseInt(undefined) // NaN
Since you cannot implement undefined.parseInt(), the only way to do it is to implement it as a static function.
As of ECMAScript 2015, parseInt has been mirrored in Number.parseInt, where it arguably makes more sense than on window. For backwards compatibility window.parseInt continues to exist though.
In this specific case it makes sense with respect to encapsulation.
Consider parseInt() - it is taking a value of an unknown type from an unknown location and extracting an integer value from it. Which object are you going to have it a method of? All of them?
String.toUpperCase() should only take a string as input (else something which may be cast as a string) and will return a string. This is well encapsulated within a small subset of cases, and since values are not strongly typed it seems logical to not have it as a global function.
As for the rest of JavaScript I have no idea nor do I have insight into the real reason it was done this way, but for these specific examples it appears to me to be a reasonable design decision.
The development progress of the JavaScript language is quite fast in recent years. With that in mind, a lot of things are still in the API due to backward compatibility - historical reasons as you said. Although I can't say that's the only reason.
In JavaScript, you can approach a problem not just with Object oriented paradigm (where methods of objects usually shares a common state). Another, functional approach can be applied quite easily without getting into too much trouble with JavaScript language.
JavaScript gives great power to its users with many possibilities of approaching a problem. There is a saying: "With Great Power Comes Great Responsibility".
Why doesen't javscript just use the strict equality operator instead of both the abstract and strict equality operators?
I asked on IRC and someone commented about Microsoft didn't want to allow the functionality of "===" to go into "==" because it would break websites. No one was able to come up with any references on this though. Shortly after another person doubted the Microsoft blame as well.
Could anyone provide information on why it came to be this way with references?
JavaScript uses type coercion to automatically convert between different types of values. Sometimes, though, one wants to distinguish between "1" and 1, or between 1 and true. That's the fundamental difference between == and === (and between != and !==). Without that distinction (if, say, === was removed), one would have to jump through hoops to test type-and-value equality (and similarly with type-independent-value testing if the functionality of == were removed).
I hadn't heard about the Microsoft story. I suspect that it is bogus and would chalk it up to a tendency on the part of some people to blame Microsoft for every perceived evil. However, I would be very surprised if Microsoft, Mozilla, Google, Yahoo, almost any experienced JS programmer, etc. would be okay with the merger of == and ===. It would indeed break a huge amount of code and would remove a very useful tool from the language.
I believe it's because they want to allow for some forms of implicit type conversion. I think the problem really comes from the fact that the rules (while well-intentioned and not too harmful individually) become monstrous when combined or in one of the "gotcha" cases typically mentioned in posts slamming "==". I personally like that there is an option, though not knowing it exists could be dangerous.
Enumerating the keys of javascript objects replays the keys in the order of insertion:
> for (key in {'z':1,'a':1,'b'}) { console.log(key); }
z
a
b
This is not part of the standard, but is widely implemented (as discussed here):
ECMA-262 does not specify enumeration order. The de facto standard is to match
insertion order, which V8 also does, but with one exception:
V8 gives no guarantees on the enumeration order for array indices (i.e., a property
name that can be parsed as a 32-bit unsigned integer).
Is it acceptable practice to rely on this behavior when constructing Node.js libraries?
Absolutely not! It's not a matter of style so much as a matter of correctness.
If you depend on this "de facto" standard your code might fail on an ECMA-262 5th Ed. compliant interpreter because that spec does not specify the enumeration order. Moreover, the V8 engine might change its behavior in the future, say in the interest of performance, e.g.
Definitely do not rely on the order of the keys. If the standard doesn't specify an order, then implementations are free to do as they please. Hash tables often underlie objects like these, and you have no way of knowing when one might be used. Javascript has many implementations, and they are all competing to be the fastest. Key order will vary between implementations, if not now, then in the future.
No. Rely on the ECMAScript standard, or you'll have to argue with the developers about whether a "de facto standard" exists like the people on that bug.
It's not advised to rely on it naively.
You should also do your best to stick to the spec/standard.
However there are often cases where the spec or standard limits what you can do. I'm not sure in programming I've encountered many implementations that deviate or extend the specification often for reasons such as the specification doesn't cater to everything.
Sometime people using specifics of an implementation might have test cases for that, though it's hard to make a reliable test case for beys being in order. It most succeed by accident or rather it's difficult behavior to reliably produce.
If you do rely on an implementation specific then you must document that. If your project requires portability (code to run on other people's setups out of your control and you want maximum compatibility) then in this case it's not a good idea to rely on an implementation specific such as key order.
Where you do have full control of the implementation being used then it's entirely up to you which implementation specifics you use while keeping in mind you may be forced to cater to portability due to the common need or desire to upgrade implementation.
The best form of documentation for cases like this is inline, in the code itself, often with the intention of at least making it easy to identify areas to be changed should you switch from an implementation guaranteeing order to one not doing so.
You can make up the format you like but it can be something like...
/** #portability: insertion_ordered_keys */
for(let key in object) console.log();
You might even wrap such cases up in code:
forEachKeyInOrderOfInsertion(object, console.log)
Again, likely something less overly verbose but enough to identify cases dependent on that.
For where your implementation guarantees key order you're just trans late that to the same as the original for.
You can use a JS function for that with platform detection, templating like CPP, transpiling, etc. You might also want to wrap the object creation and to be very careful about things crossing boundaries. If something loses order before reaching you (like JSON decode of input from a client over the network) then you'll likely not have a solution to that solely withing your library, this can even be just if someone else is calling your library.
Though you'll likely not need those, just make cases where you do something that might break later as a minimum and document that potential exists.
An obvious exception to that is if the implementation guarantees consistency. In that case you will probably be wasting your time decorating everything if it's not really a variability and is already documented via the implementation. The implementation often is a spec or has its own, you can choose to stick to that rather than a more generalised spec.
Ultimately in each case you'll need to make a judgement call, you may also choose to take a chance. As long as you're fully aware of the potential problems including the potential of wasting time avoiding problems you wont necessarily actually have, that is you know all the stakes and have considered your circumstances, then it's up to you what to do. There's no "should" or "shouldn't", it's case specific.
If you're making node.js public libraries or libraries to be widely distributed beyond the scope of your control then I'd say it's not good to rely on implementation specifics. Instead at least have a disclaimer with the release notes that the library is only catering to your stack and that if people want to use it for others then can fix and put in a pull request. Otherwise if not documented, it should be fixed.
I always assumed that booleans were more efficient than ints at storing an on/off value - considering that's their reason for existence. I recently decided to check if this is true with the help of jsperf, and it came up with some contrary results!
http://jsperf.com/bool-vs-int
Here is the first test I tried. Toggling the value of the on/off switch. On Chrome it's significantly faster to do this using 1/0, but on firefox it's slightly faster to do this using bool. Interesting.
http://jsperf.com/bool-vs-int-2
And here's the second test I tried. Using them in a conditional. This appears to have significant advantage for ints as opposed to bools, up to 70% faster to use 1/0 instead of booleans - on both firefox and chrome. Wtf?
I guess my question is, am I doing something wrong? Why are ints so much better at boolean's job? Is the only value of using bools clarity, or am I missing something important?
Disclaimer, I can only speak for Firefox, but I guess Chrome is similar.
First example (http://jsperf.com/bool-vs-int):
The Not operation
JägerMonkey (Spidmonkey's JavaScript methodjit) inlines the check for boolean first and then just xors, which is really fast (We don't know the type of a/b, so we need to check the type).
The second check is for int, so if a/b would be a int this would be a little bit slower.
Code
The Subtract operation.
We again don't know the type of c/d. And again you are lucky we are going to assume ints and inline that first. But because in JavaScript number operations are specified to be IEEE 754 doubles, we need to check for overflow. So the only difference is "sub" and a "conditional jump" on overflow vs. plain xor in case 1.
Code
Second example:
(I am not 100% sure about these, because I never really looked at this code before)
and 3. The If.
We inline a check for boolean, all other cases end up calling a function converting the value to a boolean.
Code
The Compare and If.
This one is a really complex case from the implementation point of view, because it was really important to optimize equality operations. So I think I found the right code, that seems to suggest we first check for double and then for integers.
And because we know that the result of a compare is always a boolean, we can optimize the if statement.
Code
Followup I dumped the generated machine code, so if you are still interested, here you go.
Overall this is just a piece in a bigger picture. If we knew what kind of type the variables had and knew that the subtraction won't overflow then we could make all these cases about equally fast.
These efforts are being made with IonMonkey or v8's Crankshaft. This means you should avoid optimizing based of this information, because:
it's already pretty fast
the engine developers take care of optimizing it for you
it will be even faster in the future.
your test was a bit off due to the definition of "function" and "var" and the call for the function. The cost to define function and variables and calling them will differ from engine to engine. I modified your tests, try to re-run with your browsers (note that IE was off because the first run was weird but consecutive runs were as expected where bool is fastest): http://jsperf.com/bool-vs-int-2/4
I don't know but in the second test it does
if(a) bluh();
vs
if(c == 1) bluh();
maybe c==1 is faster because you're comparing a value with one with the same type
but if you do if(a) then js need to check if the value evaluates to true, not just if it is true...
That could be the reason...
Maybe we need to test
if(c==1)
vs
if(a===true) with three =
For me the choice would be based on API usage. Always return that which is most useful. If I use secondary code, I'd favor methods that return booleans. This probably makes the code ready to be chained. The alternative is to provide overloaded methods.
Diggin' deep here. Regarding performance, I'm still unsure (this is why I found this thread) if booleans vs 0/1 is faster when computing and it still seems heavily browser-dependent. But take into account, that in extremely huge datasets the data has to be downloaded by the user first anyway:
"true" and "false" obv take up 4 or 5 characters respectively, whereas 0 and 1 are only 1 character. So it might save you a little bit of bandwidth at least, so less time to load and only after that is it up to the client's browser and hardware how to deal with those types, which seems pretty much negligible.
As a little bonus and to actually contribute something, since (I think?) no one mentioned it here, if you are going with the 0 and 1 approach, instead of using if-statements you can use bitwise operations to toggle between them, which should be pretty fast:
x=0;
x^=1; // 1
x^=1; // 0
This is the equivalence to using this toggle for booleans:
x=false;
x=!x; // true
x=!x; // false
One of the main ideas behind using bitwise operators in languages like C++/java/C# is that they're extremely fast. But I've heard that in javascript they're very slow (admittedly a few milliseconds probably doesn't matter much today). Why is this so?
(this question discusses when bitwise operators are used, so I'm changing the focus of this question to performance.)
This is quite an old question, but no one seemed to answer the updated version.
The performance hit that you get with JavaScript that doesn't exist in C/C++ is the cast from floating point representation (how JavaScript strores all of its numbers) to a 32 bit integer to perform the bit manipulation and back.
Nobody uses hex anymore?
function hextoRgb(c) {
c = '0x' + c.substring(1);
return [(c >> 16) & 255, (c >> 8) & 255, c & 255];
}
var c1 = hextoRgb('#191970');
alert('rgb(' + c1.join(',') + ')');
I use bitwise shift of zero in JS to perform quick integer truncation:
var i=3.141532;
var iTrunc=i>>0; //3
When would you want to use them? You would want to use them when you want to do bitwise operations. Just like you'd use boolean operators to do boolean operations, and mathematical operators to do mathematical operations.
If you are comfortable with bitwise operators it is very natural to use them for some applications. They can be used for many purposes other than an over-optimized boolean array. Of course, these circumstances don't come up very often in Javascript programming, but that's no reason why the operators shouldn't be available.
I found some good info #
http://dreaminginjavascript.wordpress.com/2009/02/09/bitwise-byte-foolish/
Apparently they perform very well these days. Why would you use them? Same reason you would anywhere else.
I'd think it's up to the implementer to make an operator efficient or inefficient. For example, there's nothing that prevents a JavaScript implementer from making a JITting VM, which turns a bitwise op into 1 machine instruction. So there's nothing inherently slow about "the bitwise operators in JavaScript".
There is an NES emulator written in JavaScript - it seems to make plenty of use of bitwise operations.
I am doubtful that bitwise operation are particularly slow in javascript. Since such operations can map directly to CPU operations, which are themselves quite efficient, there doesn't appear to be any inherent characteristic of bitwise operations that would force them to be irremediably slow in javascript.
Edit December 2015: I stand corrected! The performance hit that Javascript suffers in regards to bitwise operations comes from the need of converting from float to int and back (as all numeric variables in Javascript are stored as floating point values). Thank you to Chad Schouggins for pointing that out.
Never the less, as indicated in several responses, there exist various applications of javascript which rely on bitwise operation (ex: crytography and graphics) and which are not particularly slow... (see silky and Snarfblam on this page). This suggests that while slower than C/C++ and other languages which translate directly bitwise ops to single native CPU instructions, bitwise operations are all that sluggish.
Let's never the less entertain the possibility that some particular reasons caused the various implementers of javascript hosts to implement bitwise ops in a fashion that makes these extremely slow, and see if this even matters...
Although javascript has been used for other purposes, the most common use of this language in in providing user interface type of services.
BTW, I do not mean this in any pejorative way at all; performing these smart UI functions, and considering various constraints imposed on the language and also the loose adherence to standards, has required -and keeps requiring- talented javascript hackers.
The point is that in the context of UI-type requirements, the need for any quantity of bitwise operations susceptible of exposing the slowness of javascript in handling such operations is uncommon at best. Consequently, for typical uses, programmers should use bitwise operations where and if this approach seems to flow well with overall program/data and they should do so with little concern for performance issues. In the unlikely case of performance bottleneck arising from bitwise use, one can always refactor things, but one is better off staying clear from early optimization.
The notable exception to the above is with the introduction of canvas, on modern browsers, we can expect that more primitive graphic functions will be required of javascript hosts, and such operations can require in some cases heavy doses of bitwise operations (as well as healthy does of math functions). It is likely that these services will eventually be supported by way of javascript libraries (and even end-up as languages additions). For such libraries the common smarts of the industry will have been put to use to figure out the most efficient approaches. Furthermore and if indeed there is a weakness in javascript performance with bitwise ops, we'll get some help, for I predict that the javascript implementations on various hosts (browsers) will be modified to improve this particular area. (This would follow the typical pattern of evolution of javascript, that we've seen over the years.)
When speed is paramount, you can use them for bit-masking: http://snook.ca/archives/javascript/storing_values/
Also, if you need to support Netscape 4, you'd use them to deal with Document.captureEvents(). Not that any respectable company would have you write JS for NS4...
People do interesting things in JavaScript.
For example there are a lot of cryptography algorithms implemented in it (for various reasons); so of course bitwise operators are used.
Using JavaScript in its Windows Scripting Host JScript incarnation, you might have cause to use bitwise operators to pick out flags in values returned from WMI or Active Directory calls. For example, the User Access value of a user's record in AD contains several flags packed into one long integer.
ADS_UF_ACCOUNTDISABLE = 0x00000002;
if (uac & ADS_UF_ACCOUNTDISABLE == ADS_UF_ACCOUNTDISABLE) {
// user account has been disabled
}
Or someone's arbitrary table structure may contain such a field, accessible through ADO with JScript.
Or you may want to convert some retrieved data into a binary representation on any platform, just because:
BinaryData = "L";
BinaryString = BinToStr(BinaryData, ".", "x");
// BinaryString => '.x..xx..'
So there are numerous reasons why one might want to do bit manipulation in JavaScript. As for performance, the only way to know is to write it and test it. I suspect in most cases it would be perfectly acceptable, not significantly worse than any other of the multitude of inefficiencies these systems contain.
A lot of bitwise operations are being benchmarked here: http://jsperf.com/rounding-numbers-down/3
However, feel free to create your own performance testcase on jsPerf!