[].slice or Array.prototype.slice

后端 未结 2 1302
死守一世寂寞
死守一世寂寞 2020-12-05 14:35

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

相关标签:
2条回答
  • 2020-12-05 15:22

    That's an interesting question! Let's pull up the pros (✔️) and cons (❌) for each alternative:

    1. [].slice
      • ✔️: Is typed faster
        Two keystrokes, no shift-modifier or anything,
        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

    1. 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.

      • ✔️: 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
    0 讨论(0)
  • 2020-12-05 15:24

    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.
    0 讨论(0)
提交回复
热议问题