This question already has answers here:
Why is arr = [] faster than arr = new Array?
(5 answers)
Closed 10 years ago.
Today i was going through some posts in stackoverflow and this reply just popped up.
https://stackoverflow.com/a/2280350/548591
https://stackoverflow.com/a/11513602/548591
var name = [];
var name = new Array();
Is the literal one better in terms of performance than initializing an new Array Object.
Was reading this article now, just wanted to update.
http://yuiblog.com/blog/2006/11/13/javascript-we-hardly-new-ya/
From working on my own direct implementation of ECMA Grammar to make a parser, I can tell you this:
The Array literal [] gets parsed directly and then converted into an array object, whereas new Array() gets parsed first as a "expression", then checked for the new keyword, then what you want to create (in this case Array) and is then evaluated.
I can't tell you exactly how much performance is lost by using new Array(), it varies by the Javascript engine. V8 (Chrome) for example, pre-compiles code to optimize it, so it might get converted into a literal [] anyway, depending on how it works.
The easiest way would be to make a test function that creates a few hundred thousand arrays and measures the time for the loop with the literal declaration or the constructor initialization respectively.
Yeah, according to the tests, initialising [] is much faster than using the new Array. Besides that, the literal version si much more readable.
And this has already been asked!
Depending on the browsers, Literals appear to be up to twice as fast. That is, in browsers where there's a significant difference.
Related
I was playing with a constant string in a loop from another question…
Here it is:
str = "abcd";
for (i = 0; i < 4; i++) {
console.log(str[i]);
}
… and I ended up doing that:
for (i = 0; i < 4; i++) {
console.log("abcd"[i]);
}
I didn't know this kind of coding was working before I tried!
How is this way of doing called?
Should it be avoided for any technical reason?
Thanks for any answer.
How is this way of doing called?
I'm not aware of it having any specific name. You're just using a string literal inside the loop.
Should it be avoided for any technical reason?
With a string literal it probably doesn't matter, because string literals define primitive strings (and are likely reused by the JavaScript engine, as they're immutable). But if you were creating an object every time, that would be unnecessary overhead compared with just creating it once and reusing it.
For instance, if you were doing this:
for (var i = 0; i < 4; i++) {
console.log([1, 2, 3, 4][i]);
}
That code tells the JavaScript engine to create that array each time the loop body runs, which is fast, but not instantaneous. (The JavaScript engine might be able to analyze the code and optimize it if the code were used enough that it seemed worth bothering, but that's a different topic.)
The way to tried is okay but not very useful as if you specify the string in the loop it becomes static to the loop.
It is advised to use Variable insteads of "HARDCODED" values.
All your code really does is do away with the variable and index the "array-like" object directly.
Strings are "array-like" objects. They have .length property and can be indexed just as Arrays can be. They are not however, actual arrays and don't support the full Array API. JavaScript is full of "array-like" objects and they are certainly not anything to be avoided. To the contrary, it is a great feature of the language to be able to leverage this. It's just important to know when you have an actual Array and when you have an "array-like" object, so you don't use the latter incorrectly.
So, because "abcd" is array-like, there is no reason you can't place an index right after it:
"abcd"[2]
Scott Marcus explains what's happening here well. As far as whether this should be avoided, many believe it is better to access chars in a string using chatAt() instead of bracket notation. Namely because:
Bracket notation is part of ECMAScript 5 and therefore not universally supported
The similarity to bracket notation of an array or hash object can be confusing. For instance, strings are immutable so you cannot set the value of a string at a certain index as you can with an array or hash. Using chatAt() can therefore elucidate that one should not expect this to be possible.
Source:
string.charAt(x) or string[x]?
This question already has answers here:
What are the rules for JavaScript's automatic semicolon insertion (ASI)?
(7 answers)
Closed 6 years ago.
What's so terribly wrong about the following code
var obj = {a:1}
[1,2,3].forEach(console.log)
that Babel produces this malfunctional concoction?
var obj = { a: 1 }[(1, 2, 3)].forEach(console.log);
for any of ES201[567] preset. Verified with https://babeljs.io/repl.
Yes, terminating the first line with semicolon helps. Is it still a dangerous practice to not use semicolons?
UPDATE: before downvoting on the grounds of "gosh of course you should use semicolons", please acknowledge the evolution of not using them, along with arrow functions and ever growing toybox of array/object prototype functions. All modern JS examples do that, and ES6 newbie gets confused easily.
The problem is eluded to in the code compiled by Babel: the two lines you have given it are interpreted as one.
Is it still a dangerous practice to not use semicolons?
In my opinion, no. White-space is collapsed in JavaScript meaning multiple lines can be interpreted as one, so there are a few cases in which they are necessary, but whether this means that using semi-colons is an absolute must is really down to personal preference. Some people feel very strongly that you should, and they may well be right...
Anyhow, as you discovered, one of these cases is ending a line with an object or array and starting the next with an array literal ([]). You can read about the remaining cases here.
If the code you are working on does not use semi-colons, for example if it uses the standard code style, you can..
..add a semi-colon to the end of the first line:
var obj = {a:1};
[1,2,3].forEach(console.log)
..add a semi-colon to the beginning of the second line:
var obj = {a:1}
;[1,2,3].forEach(console.log) // beginning of last line
..avoid having to use a semi-colon at all by assigning the array literal to a variable:
var obj = {a:1}
var arr = [1,2,3]
arr.forEach(console.log)
____
Side note...
The reason the contents of your array literal are wrapped in brackets is because Babel has interpreted your array literal as an attempt to access a property on the object literal defined in the previous line. Of course, you can only access one property at a time using the array[index] syntax, so Babel uses the comma operator to take a single value from (1, 2, 3), which will be 3.
Read about the comma operator on MDN.
What are the advantages of using
var foo = [];
over using
var bar = new Array();
i've been told to use [] over new Array() but never with much explanation
The main reason to use [] as opposed to new Array() is the arguments you pass. When you use new Array(10), you create an empty array with 10 elements, but when you use [10], you create an array with one element who's value is 10. Since this is generally the information most programmers want to pass to an array (as arrays are dynamic in Javascript), this is generally considered the best practice. Also new Array(10,20) works differently than new Array(10). In this case you have the same effect as [10,20] which is to create an array with 2 elements, 10 and 20. Since this is... strange at best... it's easy to accidentally create an empty array by passing new Array() only one value. [] always has the same effect, so I'd also recommend sticking with it.
shorter
arguments of Array are confusing (e.g. new Array(10) and new Array("10") are quite different)
Both can be used as good. This discussion/confusion has started since Javascript guru Douglas Crockford told that the new keyword is considered harmful. Since then it was considered "good practice/technique" to leave out the new keyword to avoid unexpected results/behaviour. Also see this Stackoverflow topic.
Three reasons (the first two expanded upon in other answers):
Shorter;
Allows creation of arrays with one element, as detailed in Chibu's answer;
Works even in the unlikely event of the Array constructor having been overwritten.
Non-reasons:
Avoidance of the new operator. Don't be afraid of new just because Douglas Crockford was once bitten by it. It's extremely useful.
It scores you less symbols in code golf.
It's the same thing. The only reason to use [] over new Array() is that it's shorter.
shorter and cleaner. Should use {} to create objects as well.
This question already has answers here:
What’s the difference between "Array()" and "[]" while declaring a JavaScript array?
(19 answers)
Closed 8 years ago.
Is there any difference between these three ways of creating an array? If not, why do the first two ways exist if they're just more code?
1:
var myCars=new Array();
myCars[0]="Saab";
myCars[1]="Volvo";
myCars[2]="BMW";
2:
var myCars=new Array("Saab","Volvo","BMW");
3:
var myCars=["Saab","Volvo","BMW"];
Using [] is more secure and reliable than using new Array(). The former is actually recommended. This is because the value of Array can be overridden. Also, [] is faster compared to new Array().
Take a look at these related questions:
What’s the difference between “Array()” and “[]” while declaring a JavaScript array?
JSLint: “Use the array literal notation []” for var os_map = {}
What's wrong with var x = new Array();
Is JavaScript 's “new” Keyword Considered Harmful?
A related link:
JSLint wants you to avoid new.
To clarify what "overridden" means, you can do something like this:
function Array() {
alert("I am not really an array! BWAHAHAHAHAHA!");
}
Now when you do new Array(); you will get an alert, which is obviously not what you want.
In short, there really is no pressing need to to use new Array() and it doesn't buy you anything more compared to using the literal [].
Difference:
In 1st method, array declaration and array initialization are done separately. In 2nd and 3rd method, array declaration and array initialization is done in a single statement. 3rd is just a shorthand for 2nd method.
Need:
Case 1: Let's say you have no cars today, but you intend to buy one in the future.So,
var myCars = new Array();
Case 2: Let's say you own 2 cars today. But in future, you might buy/sell one or more cars.
var myCars = new Array("BMW", "Porsche");
To conclude, if you know the data before hand, you use 2nd or 3rd method but if you don't know the data before hand, you use 1st method.
For Arrays there is not a significant difference between the 2 approaches, other than readability and a very slight performance advantage for the plain notation.
However the general recommended practice is to use the plain notation when possible for javascript rather than wrapping these things in a constructor. Because while 'new Array()' and 'new Object()' produce the same as [] and {}, using constructors for primitives actually can cause issues.
For instance new String() will create a String object rather than a primitive string. This has the disadvantage of preventing the use of === and other comparisons on the string.
For example
alert(new String("") === new String("")); //false alert ("" === "")
//true
So while there is no difference in this particular case, in general its better to get in the habit of using the basic notation rather than using constructors for built in types.
Clarification
When I say no difference, I mean that in the general case those notations will produce the same result. Vivin's points are excellent and are another reason for avoiding this notation.
I read a few questions and answers about javascript dictionary implementations, but they don't meet my requirements:
the dictionary must be able to take objects as keys
the values must be accessible by the []-operator
So I came up with the idea to overwrite the valueOf-method in Object.prototype, as follows:
Object.__id__ = 0;
Object.prototype.valueOf = function() {
if(!this.__id__)
this.__id__ = ++Object.__id__;
return "__id__" + this.__id__;
}
Object.prototype.toString = Object.prototype.valueOf;
//test
var x = {p1: "5"};
var y = [6];
var z = {};
z[x] = "7";
z[y] = "8";
console.log(z[x], z[y]);
I tested this with google-chrome and it seems to work well, but I'm a bit sceptical, whether this will cause some drawbacks, since it was so easy to implement.
Considering that the valueOf method is not used for other purposes in the whole code, do you think there are any disadvantages?
It's an interesting idea. I suggest my jshashtable. It meets your first requirement but not the second. I don't really see the advantage of insisting on using the square bracket property access notation: do you have a particular requirement for it?
With jshashtable, you can provide a hashing function to the Hashtable constructor. This function is passed an object to be used as a key and must return a string; you could use a function not dissimilar to what you have there, without having to touch Object.prototype.
There are some disadvantages to your idea:
Your valueOf method will show up in a for...in loop over any native object;
You have no way determining which keys should be considered equal, which is something you may want to do. Instead, all keys will be considered unique.
This won't work with host objects (i.e. objects provided by the environment, such as DOM elements)
It is an interesting question, because I had so far assumed that any object can be used as an index (but never tried with associative arrays). I don't know enough about the inner workings of JavaScript to be sure, but I'd bet that valueOf is used somewhere else by JavaScript, even if not in your code. You might run into seemingly inexplicable problems later. At least, I'd restrict myself to a new class and leave Object alone ;) Or, you explicitly call your hashing function, calling it myHash() or whatever and calling z[x.myHash()] which adds clutter but would let me, personally, sleep better ;) I can't resist thinking there's a more JavaScript-aware solution to this, so consider all of these ugly workarounds ;)
If you came upon this question looking for a JS dictionary where objects are keys look at Map Map vs Object in JavaScript