Extending Built-in Classes
On this page
JavaScript Extending Built-in Classes (JavaScript扩展内置类)
Array, Map, and other built-in classes are extendable. (Array、Map和其他内置类是可扩展的。)
In the example below, NumsArray inherits from the native Array:
// add another method to it (can do more)
class NumsArray extends Array {
isEmpty() {
return this.length === 0;
}
}
let arr = new NumsArray(1, 3, 6, 11, 27);
console.log(arr.isEmpty()); // false
let filterArr = arr.filter(item => item >= 10);
console.log(filterArr); // 11, 27
console.log(filterArr.isEmpty()); // false
The most impressive thing is that built-in methods such as map, filter, and more - return new objects of literally the inherited type NumsArray. (最令人印象深刻的是,内置方法(如map、filter等)返回字面上继承类型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. (当调用arr.filter ()时,它会在内部使用arr.constructor而不是basic Array生成新的结果数组。)
Moreover, that behavior can be customized. (此外,这种行为可以定制。)
You can add to the class a unique static getter Symbol.species. In the case of its existence, it may return the constructor, which JavaScript will apply internally for creating new entities in the filter, the map, and more. If you want built-in methods such as map or filter to return ordinary arrays, you may return Array in Symbol.species, as follows:
class NumsArray extends Array {
isEmpty() {
return this.length === 0;
}
// built-in methods will use this as the constructor
(//内置方法将使用this作为构造函数)
static get[Symbol.species]() {
return Array;
}
}
let arr = new NumsArray(1, 3, 6, 11, 27);
console.log(arr.isEmpty()); // false
// filter creates new array using arr.constructor[Symbol.species] as constructor
let filterArr = arr.filter(item => item > 10);
// filterArr is not NumsArray, but Array
console.log(filterArr.isEmpty()); // Error: filterArr.isEmpty is not a function
So, it can be assumed that now .filter returns Array. Hence, the extended functionality is not passed further. (因此,可以假设现在.filter返回Array。因此,扩展功能不会被进一步传递。)
Other collections, like Map and Set, work similarly using Symbol.species, also. (其他集合(如Map和Set )的工作方式类似于使用Symbol.species。)
No Static Inheritance in Built-ins
No Static Inheritance in Built-ins (内置中没有静态继承)
There are different static methods for built-in objects. For example, Array.isArray, Object.keys, and more. (内置对象有不同的静态方法。例如, Array.isArray、Object.keys等。)
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. (例如, Date和Array都继承自Object ,因此它们的实例具有来自Object.prototype的方法。但是Array. [[Prototype]]无法引用Object ,因此没有任何Array.keys () (或Date.keys () )静态方法。)
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. (因此, Date和Object之间没有任何链接。但是Date.prototype继承自Object.prototype。)
It’s a notable inheritance difference between built-in objects in comparison to what is received with extends. (与使用extends接收的对象相比,内置对象之间存在明显的继承差异。)