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.
Related
Just wondering what's the different with the following js script.
[].slice.call(this) vs Array.prototype.slice.call(this);
They seems to be doing this same, can someone explain the different and which one i should stick with?
Cheers
They are almost identical. Let's examine each of them:
[].slice.call(data)
What it does?
[] - this creates new Array, same to new Array()
slice - it retrieves method slice from array
call(data) - it calls slice() method replacing its current context with data variable, i.e. uses data as its internal array, not []. This returns our data converted into Array.
Now, the second one:
Array.prototype.slice.call(data)
This one:
Array.prototype.slice - retrieves method slice from Array.prototype; in a nutshell - it returns you slice method without any context (internal data).
call(data) - as in previous variant, calls this method with data as its context.
Conclusion
Both [].slice and Array.prototype.slice return you a slice function which you can call on some array, however this array is passed not as argument, but as context (using call method of function object). In JavaScript, these calls will be absolutely the same:
// Calling as a method of 'Hello' string
'Hello'.indexOf('e') // returns 1
// Calling as unbound method
String.prototype.indexOf.call('Hello', 'e') // returns 1
String.prototype.indexOf.apply('Hello', ['e']) // returns 1
Those methods are almost the same. First one is more readable, but second one uses a bit less memory because it isn't creating a temporary initial Array.
I believe that Array doesn't actually create an object, where as [] is an instance of Array.
Definitely stick with the latter one as the first one is an implicit array construction and the same as:
new Array().slice.call(this)
Its constructing a new array that needs to be garbage collected afterwards since you dont use it. While both statements "work", the above mentioned does a lot of extra work, first you construct a new instance, then you look up if the instance itself has a slice property, as this is false the prototype chain is traversed and the slice is found on the Array.prototype and then called. Then you call it with your other array as scope, so essentially render the instance you created useless by using your other one.
Thats why Array.prototype.slice.call(myarr) is the proper way of accessing the slice method.
Array.prototype.slice.call() seems slightly more performant, though that makes sense because it would be quicker at runtime to "look up" this method. I posit that [].slice.call() is the best choice. Here's the jsperf of reference
Let's be real, in what case would the negligible difference between the two be a major contributor to poor website performance? sounds like heaven, actually. The shorter syntax of the literal method is awesome. I'd rather save myself the half-second it'd take to type the prototype variant than be shakily more efficient.
The coffin nail of Array.prototype... some people say is that it's irresponsible because you risk altering it. But... that's stupid. Figure 1: Array.prototype = function() { console.log('foo') }; Whoopsie... That probably happens all of the time. Seriously, even granting its legitimacy is still intact, it takes me longer to type and is imo hideous compared to its sexier literal sister.
The real answer to your real question is that the functionality is exactly the same. Use whichever you will still appreciate on your deathbed.
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.
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.
I’v come across both ways to apply Array prototypes to a native object:
arr = Array.prototype.slice.call(obj);
arr = [].slice.call(obj);
In similar fashion, getting the true type of a native array-like object:
type = Object.prototype.toString.call(obj);
type = {}.toString.call(obj);
A simple test:
function fn() {
console.log(
Array.prototype.slice.call(arguments),
[].slice.call(arguments),
Object.prototype.toString.call(arguments),
{}.toString.call(arguments)
);
}
fn(0,1);
Fiddle: http://jsfiddle.net/PhdmN/
They seem identical to me; the first syntax is used more often, but the second is definitely shorter. Are there any shortcomings when using the shorter syntax?
They are identical regarding functionality.
However, the Array object can be overwritten, causing the first method to fail.
//Example:
Array = {};
console.log(typeof Array.prototype.slice); // "undefined"
console.log(typeof [].slice); // "function"
The literal method creates a new instance of Array (opposed to Array.prototype. method). Benchmark of both methods: http://jsperf.com/bbarr-new-array-vs-literal/3
When you're going to use the method many times, the best practice is to cache the method:
var slice = Array.prototype.slice; //Commonly used
var slice = [].slice; - If you're concerned about the existence of Array, or if you just like the shorter syntax.
That's an interesting question! Let's pull up the pros (✔️) and cons (❌) for each alternative:
[].slice
✔️: Is typed faster
Two keystrokes, no shift-modifier or anything,
and your linter knows [.slice is a typo.
✔️: Is read faster
You can identify the relevant part (slice) faster.
✔️: Is more popular
56M+ snippets on GitHub (as of late 2018).
✔️: Can't be overwritten
The first part of Rob's answer demonstrates this perfectly.
✔️: Runs faster.
Wait, what? Well, that's actually the whole point of this answer.
Contrary to what you'd think and read pretty much everywhere, [].slice.call(...) does NOT instantiate a new, empty Array just to access its slice property!.
Nowadays (it has been so for 5+ years – as of late 2018), the JIT compilation (1) is included everywhere you run JavaScript (unless you're still browsing the Web with IE8 or lower).
This mechanism allows the JS Engine to: (2)
... resolve [].slice directly, and statically, as direct Array.prototype reference in one shot, and just one configurable property access: forEach
Array.prototype.slice
❌: Is typed slower
Typos (e.g.: Array.prorotype.slice) look fine until you try and run the code.
❌: Is less popular
8M+ snippets on GitHub (as of late 2018).
❌: Runs slower
Array.prototype.slice is: (2)
... a lookup for the whole scope for an Array reference until all scopes are walked 'till the global one ... because you can name a variable Array any time you want.
Once the global scope is reached, and the native found, the engine accesses its proottype and after that its method
...
O(N) scope resolution + 2 properties access (.prototype and .forEach).
✔️: Allows you to seamlessly adapt to whichever coding conventions would strictly prevent you from having a line start with either (, [ or `
Definitely a good thing (sarcastically).
✔️: You won't have to explain why [].slice is better in pretty much every way.
Although now, that would just boil down to clicking the share link below 👌
Disclaimer
Note that, realistically, neither does effectively run faster than the other. This isn't the bottleneck of your application.
You may want to read A crash course in just-in-time (JIT) compilers
Quoted from Andrea Giammarchi (#WebReflection on Twitter)
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