Разделение на подклассы Массивов JavaScript. TypeError: Array.prototype.toString не универсален

Действительно ли возможно разделить на подклассы и наследоваться Массивам 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?

34
задан Tauren 16 July 2010 в 02:46
поделиться

2 ответа

Юрий Зайцев ( @kangax ) только что опубликовал действительно хорошую статью на эту тему.

Он исследует различные альтернативы, такие как метод Дина Эдвардса заимствования iframe , прямое расширение объекта, расширение прототипа и использование свойств доступа ECMAScript 5.

В конце концов, не существует идеальной реализации, у каждой есть свои преимущества и недостатки.

Определенно хорошее чтение:

34
ответ дан 27 November 2019 в 16:50
поделиться

Я пытался сделать подобное раньше; обычно это просто не происходит. Однако вы, вероятно, можете сымитировать это, применяя внутренние методы 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, является довольно общим.

1
ответ дан 27 November 2019 в 16:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: