JavaScript. After inheriting the array, the filter function will be broken.

I think I found a bug in zombie .

This code works:

function twoArguments(a, b) { }

function threeArguments(a, b, c) { }

let pipeline = new Array();
pipeline.push(twoArguments);
pipeline.push(threeArguments);

let onlyTwoArgumentsFuncs = pipeline.filter(fn => fn.length === 2);
console.log(onlyTwoArgumentsFuncs);

      

But the following code does not filter out any two function arguments:

class Pipeline extends Array {

    constructor() {
        super();
        this.push(twoArguments);
        this.push(threeArguments);
    }

    run() {
        return this.filter(fn => fn.length === 2);
    }

}

let pipeline = new Pipeline();
let onlyTwoArgumentsFuncs = pipeline.run();
console.log(onlyTwoArgumentsFuncs);

      

Still returns both functions. Please explain why.

+3


source to share


3 answers


Setting Symbol.species

to the original constructor Array

fixes this

class Pipeline extends Array {
    static get [Symbol.species]() { return Array; }

    // ...
}

      



EDIT : The
Array.prototype.filter

implementation does not mutate the original object, but creates a new one to keep the result. In this case, a derived constructor is used for this, which fills the object with exactly 2 values ​​for each init.

You can set Symbol.species

in a derived class to instruct the filter

original constructor to be used Array

. Or you can remove the initialization from the class and use new Pipeline(twoArguments, threeArguments)

or Pipeline.of(…)

as @Bergi suggests.

+4


source


Instead of prototyping new methods just a variable with the say fat arrow =>

function, the es6 functions worked here

run = () => {

      



function twoArguments(a, b) { }

function threeArguments(a, b, c) { }


class Pipeline extends Array {

    constructor() {
        super();
        this.push(twoArguments);
        this.push(threeArguments);
    }

    run = () => {
        return this.filter(fn => fn.length === 2);
    }

}

let pipeline = new Pipeline();
let onlyTwoArgumentsFuncs = pipeline.run();
console.log(onlyTwoArgumentsFuncs);
      

Run code


0


source


Another possible solution is to create Array

explicitly before filtering:

run() {
    return [].concat(this).filter(fn => fn.length === 2);
}

      

0


source







All Articles