Can I be sure that array.slice () will always work the same way as array.slice (0)?

I always used the .slice() method .slice() no arguments to make a copy of the JavaScript Array . This works great in every browser and in the JavaScript environment I tried: it handles the same thing as .slice(0) .

It’s just a matter of style, but omitting the start argument makes it clearer that we don’t take any special piece of the array, but want to get a copy of it all.

However, both MDN and MSDN say that the first argument to array.slice() is required. Only the second argument is optional. Other online sources such as TutorialsPoint and W3Schools will say the same. (No, I do not recommend W3Schools! Just indicating that they agree with MDN and MSDN on this issue.)

Am I really lucky with this? Could there be a browser or other JavaScript environment where array.slice() not working?

+4
source share
1 answer

All of these online links are erroneous.

At least if we are talking about standards-compliant browsers and runtimes.

the ECMA-262 standard requires some appropriate implementation to handle array.slice() identically to array.slice(0) .

This is how we know it.

First, consider section 15.4.4.10 , "Array.prototype.slice (start, end)":

The slice method takes two arguments: start and end, and returns an array containing the elements of the array, starting from the element, starting at the end of the element, and not ending (or ending with the end of the array if the end is undefined ) & hellip;

What is it? There is even a mention of the end is not optional. Are both a beginning and an end required?

Yes they are. But we need to look elsewhere to understand what that means.

Section 15 , “Standard Built-in ECMAScript Objects,” says (in the fourth paragraph):

Unless otherwise specified in the description of a particular function, if the function or constructor described in this section has fewer arguments than are required for the function, the function or constructor should behave exactly as if sufficient additional arguments were provided to it, each of which is undefined .

And this is consistent with how other methods are indicated. For example, we know that the argument of the comparison function for array.sort() is optional, but Section 15.4.4.11 "Array.prototype.sort (comparefn)" says nothing that the comparefn argument is optional. It just describes what to do if comparefn is undefined or not.

So now we know that array.slice() interpreted as array.slice(undefined,undefined) . Then, continuing with section 15.4.4.10 , we find the appropriate step:

5. Let relativeStart - ToInteger (start).

ToInteger is described in section 9.4 , where the first two steps are important:

1. Let the number be the result of calling ToNumber on the input argument.
2. If the number is NaN , return +0 .

ToNumber is located in section 9.3 , where the first entry in the table indicates that when its argument type is Undefined, the result is NaN .

So, the missing first argument to array.slice() treated as undefined , and this value is passed to ToNumber, which returns NaN . This causes ToInteger to return 0 (or +0 , as they call it here), and that the value of array.slice() .

Therefore, array.slice() same as array.slice(0) . If the implementation does not apply to it like that, it does not comply with the ECMA-262 standard.

Of course, this is the standard, and then there is the real world.

If we do the same analysis for the second argument .slice() , we conclude that they should all work the same way (among other similar options):

 array.slice() array.slice( 0 ) array.slice( undefined ) array.slice( 0, undefined ) array.slice( undefined, undefined ) 

However, as @ Pumbaa80 points out in a comment, the last two versions do not work in IE8 (and in IE7)!

But at least the simple case of array.slice() , which I was worried about, works in these old browsers and should continue to work in any browser or at runtime that follows the standard.

+9
source

Source: https://habr.com/ru/post/1496508/


All Articles