I'm new to OOP in ES6 and trying to understand how to extend Array so i can create pipelines. I'm starting with a simple case of extending Array
ad overriding Array.filter
, and expecting result.hasOwnProperty("filter")
to be true
... but it's not:
So how do you test that the method filter now lives in the Wordlist class?
export class Wordlist extends Array{
constructor(...args){
super(...args)
}
filter(...args){
console.log("filtering")
return super.filter(...args)
}
}
// test
describe.only('Wordlist.filter', ()=>{
it('should filter an array', ()=>{
const wordlist = new Wordlist('hello', 'rhubarb')
const result = wordlist.filter(word => word === 'rhubarb')
expect(result.length).toEqual(1) // pass
expect(result).toEqual(["rhubarb"]) // pass
expect(result.hasOwnProperty('filter')).toBe(true) // should pass but doesnt!!!
expect(result.hasOwnProperty('reduce')).toBe(false) // passes
})
})
CodePudding user response:
The misunderstanding is about how .hasOwnProperty()
works. This returns a boolean that indicates whether an object directly contains a specific property. In your case, you are defining a property for the class which puts the new .filter()
property on the object's prototype which means that the .filter()
property is NOT directly on the object, but is inherited from the object's prototype.
So, by definition when the property is only on the prototype, .hasOwnProperty()
will return false
.
If you want to see if result
is actually a Wordlist
object, then you can use:
result instanceof Wordlist // should be true
to test for that. You could also do this:
Object.getPrototypeOf(result).hasOwnProperty('filter') // should be true
And, to make sure it's not the same .filter
as an array has, you could check this:
result.filter !== [].filter // should be false