Я ищу любые указания, будет ли "суперклассификация" встроенного типа работать в соответствии со спецификацией. То есть, учитывая любую гипотетическую согласованную реализацию ECMAScript, делает ли "суперклассирование" встроенный разрыв среды выполнения, влияя на алгоритм создания конструктора класса?
"Суперклассируемый", термин, который я использую, относится к классу, объекты которого возвращаются путем его построения или называются его функцией, если это применимо, будут созданы с одинаковыми внутренними слотами (кроме [[Prototype]]), независимо от того, из того, что является его прямым суперклассом, до тех пор, пока исходный [[Прототип]] конструктора класса и прототипа класса все еще находится в каждой соответствующей цепочке наследования после переназначения их. Следовательно, для того, чтобы быть "суперклассифицированным", класс не должен называть super()
во время создания.
Когда "суперклассирование" Array
, я ожидаю, что он будет выглядеть примерно так:
// clearly this would break Array if the specification allowed an implementation
// to invoke super() internally in the Array constructor
class Enumerable {
constructor (iterator = function * () {}) {
this[Symbol.iterator] = iterator
}
asEnumerable() {
return new Enumerable(this[Symbol.iterator].bind(this))
}
}
function setSuperclassOf (Class, Superclass) {
/* These conditions must be satisfied in order to
* superclass Class with Superclass
*/
if (
!(Superclass.prototype instanceof Object.getPrototypeOf(Class.prototype).constructor) ||
!(Superclass instanceof Object.getPrototypeOf(Class).constructor) ||
(Superclass.prototype instanceof Class)
) {
throw new TypeError('${Class.name} cannot have their superclass set to ${Superclass.name}')
}
// Now we can superclass Class with Superclass
Object.setPrototypeOf(Class.prototype, Superclass.prototype)
Object.setPrototypeOf(Class, Superclass)
}
setSuperclassOf(Array, Enumerable)
const array = new Array(...'abc')
// Checking that Array is not broken by Enumerable
console.log(array[Symbol.iterator] === Array.prototype[Symbol.iterator])
// Checking that Enumerable works as expected
const enumerable = array.asEnumerable()
console.log(array instanceof Enumerable)
console.log(!(enumerable instanceof Array))
for (const letter of enumerable) {
console.log(letter)
}