I have this example code:
class TestClass extends Array {
constructor() {
console.log( 'constructor' );
let ar = [];
ar.push( { id: 1, name: 'a' } );
ar.push( { id: 2, name: 'b' } );
ar.push( { id: 3, name: 'c' } );
ar.push( { id: 4, name: 'd' } );
// finalizing object
super( ...ar );
}
Foo() {
console.log( 'foo' );
return this.filter( item => item.id > 2 );
}
}
let t = new TestClass();
console.log( t.Foo() );
It is simpler version of what I've already written. My app worked up till now, but stopped the moment I needed to filter data in my extended array.
I've found out, that the problem is that calling a filter function on an object of my class internally calls constructor. The above code shows that example.
Is there any way to bypass this issue, because I can't call constructor again at this point. Also, I've found out (using this simple TestClass
) that actual output is not what I would expect - I get an array of 4 items with id's 3, 4, 3, 4. Can anyone explain what's happening here?
Symbol.species
provides a way to return not another instance of the derived class but for .e.g. in this case an Array
instance again.
class TestClass extends Array {
constructor() {
console.log( 'constructor' );
let ar = [];
ar.push( { id: 1, name: 'a' } );
ar.push( { id: 2, name: 'b' } );
ar.push( { id: 3, name: 'c' } );
ar.push( { id: 4, name: 'd' } );
// finalizing object
super( ...ar );
}
static get [Symbol.species]() { return Array; }
Foo() {
console.log( 'foo' );
return this.filter( item => item.id > 2 );
}
}
let t = new TestClass();
let a = t.Foo();
console.log('a : ', a);
console.log('(a instanceof Array) ? ', (a instanceof Array));
console.log('(a instanceof TestClass) ? ', (a instanceof TestClass));
.as-console-wrapper { max-height: 100%!important; top: 0; }