In the example below, NumsArray inherits from the native Array:
The most impressive thing is that built-in methods such as map, filter, and more - return new objects of literally the inherited type NumsArray.
Their internal implementation applies the constructor property of the object for that. So, in the example mentioned above, it looks like this:
arr.constructor === NumsArray
When you call arr.filter(), it internally generates the new array of results using arr.constructor and not basic Array.
Moreover, that behavior can be customized.
So, it can be assumed that now .filter returns Array. Hence, the extended functionality is not passed further.
Other collections, like Map and Set, work similarly using Symbol.species, also.
No Static Inheritance in Built-ins
There are different static methods for built-in objects. For example, Array.isArray, Object.keys, and more.
As you have already learned, native classes extend one another: Array extends Object.
Typically, when a class extends another one, the static and non-static methods are inherited. It was already explained in the chapter Static properties and methods. Please, take into account that built-in classes are an exception: they don’t inherit statics from one another.
For instance, both Date and Array inherit from Object, hence their instances have methods from Object.prototype. But Array.[[Prototype]] can’t reference Object, hence there isn’t any Array.keys() (or Date.keys()) static method.
The picture structure for Date and Object looks like this:
So, no link can be noticed between Date and Object. But Date.prototype inherits from Object.prototype.
It’s a notable inheritance difference between built-in objects in comparison to what is received with extends.