ES6 classes offer a significant benefit in that they can subclass unique classes like arrays. Attempting to subclass arrays in older versions of Javascript can be done, but the process is not worth explaining here.
Another issue arises when using a subpar pattern of subclassing in pre-ES6 Javascript. In this scenario, the base class is instantiated, and an instance of the base class is added to the new class's prototype chain without proper linkage. TypeScript utilizes a similar method internally, but with flawed assumptions. In the provided code, the Array constructor is already executed before the list of cities is added, resulting in a failure even if subclassing arrays in this manner was possible.
The presented code showcases the contemporary approach to achieving this task. By addressing the concerns raised in Eleazar's link, the constructor's arguments are not directly passed to the Array base constructor. Instead, the base constructor generates an empty array, followed by adding the values into it.
class randomArr extends Array{
constructor(..._items){
super()
_items.forEach(_=>this.push(_))
}
getRandomValue(){
const index=Math.floor(this.length*Math.random())
return this[index]
}
}
let arr=new randomArr('seoul', 'tokyo', 'beijing')
console.log(arr.getRandomValue())
Contrary to Eleazer's recommendation, it is advisable to refrain from adding named properties to core prototypes. Symbol properties are a more suitable option for this purpose. The following demonstrates how to implement this:
const getRandomValue=Symbol()
Reflect.defineProperty(
Array.prototype,
getRandomValue,
{
value(){
const index=Math.floor(this.length*Math.random())
return this[index]
}
}
)
let arr=['seoul', 'tokyo', 'beijing']
console.log(arr[getRandomValue]())
The use of symbols ensures that there are no conflicts with other libraries extending the Array prototype.