var testElements = document.getElementsByClassName('test'); var testDivs = Array.prototype.filter.call(testElements, function(testElement { return testElement.nodeName === 'DIV'; }); 

There is such a piece of code that is sorting out all divs. I do not understand:

  1. Why is the prototype Array.prototype called, and not just testElements.filter (...). Is this because Array.prototype converts testElements into an array or why?

    2 answers 2

    getElementsByClassName - returns not an array, but an HTMLCollection . The resulting object does not have a filter method.

    In turn, the filter method is a generalized method, and it can be applied not only to arrays, but also to objects that have the property length , which is a number greater than 0.

    In order to apply this method not to an array, you need to get it separately and call its call method, which sets the passed object as context

    • "The ingenious answers are most likely retold help, because they completely lack human experience, which is so lacking for beginners." (c) OlmerDale: D - Aleksey Shimansky

    Items returned are of a type other than an array. This is the so-called collection. To be able to work with it as with an array, you need to convert it into an array.

    You can convert into an array any object whose keys are cast to an integer type and have a length property that contains the index of the last element + 1.

    1. Because testElements is not an array, it does not have a filter method. Array.prototype does not convert anything. It indicates that you need to refer to the filter method of the prototype of the Array constructor, and not the filter method of the testElements itself.

    2. And this is the second part. call as the first argument takes the context in which the method will be executed (what will be this inside). So you say this line

      Array.prototype.filter.call(testElements)

      " Array.prototype the filter method from Array.prototype and call it on the testElements pseudo- testElements ."

    By the way, similar behavior can be achieved as follows:

     [].filter.call(testElements); 

    In this case, the interpreter will first look for the filter method on the object itself (the array), where it will not find it and continue to search for the __proto__ link, which points to the same Array.prototype . Still, the first option is preferable, because there is no initialization of the new array, even if empty.

    • Thanks for the answer. - 200OK
    • I will add that you can make an array from the resulting collection using Array.from( testElements ) and it will have all the methods available for arrays, including filter . - ivan.posokhin
    • @ ivan.posokhin yes it is possible and in the old manner - the same slice. - smellyshovel