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 arraycall(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.
[].slice(), it will return an empty array [], and if you do [1,2,3].slice(), [1,2,3] will be returned. And, on the other hand, calling Array.prototype.slice() directly (without .call) will always return [] because it has no internal context, it's smth like "static metod".slice always returns a new array. So calling slice is an array construction as well. Also the memory usage is not really the crux here but the CPU time to construct and garbage collect these arrays can be problematic in high performance applications.Array.prototype.slice() directly ... will always return [] because it has no internal context" That's not exactly true. In that case, this will refer to Array.prototype. And it so happens that Array.prototype.length is 0. That's why you get an empty 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.
Object.getPrototypeOf([]).slice.call() a happy compromise?
Array, notarray, right?Array.prototype.callis incorrect. Maybe you meantArray.prototype.slice.call()?Array.prototype.slice === [].slice. It's the same function, just two different ways to get a reference to it.Array.from.