Действительно ли возможно разделить на подклассы и наследоваться Массивам JavaScript?
Я хотел бы иметь свой собственный объект Массива, который имеет все функции Массива, но содержит дополнительные свойства. Я использовал бы myobj instanceof CustomArray
выполнить определенные операции, если экземпляром является мой CustomArray.
После попытки разделить на подклассы и столкновение с некоторыми проблемами, я нашел эту статью Dean Edwards, которая указывает на выполнение, это с объектами Массива не работает правильно. Оказывается, что Internet Explorer не обрабатывает его правильно. Но я нахожу другие проблемы также (только протестированными в Chrome до сих пор).
Вот некоторый пример кода:
/**
* Inherit the prototype methods from one constructor into another
* Borrowed from Google Closure Library
*/
function inherits(childCtor, parentCtor) {
function tempCtor() {};
tempCtor.prototype = parentCtor.prototype;
childCtor.superClass_ = parentCtor.prototype;
childCtor.prototype = new tempCtor();
childCtor.prototype.constructor = childCtor;
},
// Custom class that extends Array class
function CustomArray() {
Array.apply(this, arguments);
}
inherits(CustomArray,Array);
array = new Array(1,2,3);
custom = new CustomArray(1,2,3);
Ввод следующего в консоли Chrome дает этот вывод:
> custom
[]
> array
[1, 2, 3]
> custom.toString()
TypeError: Array.prototype.toString is not generic
> array.toString()
"1,2,3"
> custom.slice(1)
[]
> array.slice(1)
[2, 3]
> custom.push(1)
1
> custom.toString()
TypeError: Array.prototype.toString is not generic
> custom
[1]
Очевидно, объекты не ведут себя то же. Если я разочаровываюсь в этом подходе, или есть ли некоторый способ выполнить мою цель myobj instanceof CustomArray
?
Юрий Зайцев ( @kangax ) только что опубликовал действительно хорошую статью на эту тему.
Он исследует различные альтернативы, такие как метод Дина Эдвардса заимствования iframe , прямое расширение объекта, расширение прототипа и использование свойств доступа ECMAScript 5.
В конце концов, не существует идеальной реализации, у каждой есть свои преимущества и недостатки.
Определенно хорошее чтение:
Я пытался сделать подобное раньше; обычно это просто не происходит. Однако вы, вероятно, можете сымитировать это, применяя внутренние методы Array.prototype
. Этот класс CustomArray
, хотя и протестированный только в Chrome, реализует как стандартный push
, так и пользовательский метод last
. (Почему-то в то время эта методология не пришла мне в голову xD)
function CustomArray() {
this.push = function () {
Array.prototype.push.apply(this, arguments);
}
this.last = function () {
return this[this.length - 1];
}
this.push.apply(this, arguments); // implement "new CustomArray(1,2,3)"
}
a = new CustomArray(1,2,3);
alert(a.last()); // 3
a.push(4);
alert(a.last()); // 4
Любой метод Array, который вы собираетесь использовать в своей пользовательской реализации, придется реализовать вручную, хотя вы, вероятно, можете просто проявить смекалку и использовать циклы, поскольку то, что происходит внутри нашего пользовательского push
, является довольно общим.