Унаследовать Array
Добрый день.
Почитал о наследовании в JavaScript. Вкратце, захотел сделать List, который мог бы фильтровать добавляемые в него данные, при этом весь функционал чтобы повторял обычный Array. Вот к чему пришёл: util.List = function () { Array.apply(this, arguments); }; util.List.prototype = new Array(); util.List.prototype.move = function (from, to) { if (typeof from === 'string') { from = Number(from); } if (typeof to === 'string') { to = Number(to); } if (typeof to !== 'number' || (typeof to === 'number' && isNaN(to)) ) { return false; } if (typeof from !== 'number' || (typeof from === 'number' && isNaN(from)) ) { return false; } if (typeof this['onMove'] === 'function') { if (this.onMove(from, to) === false) { return false; } } var tmp = this.splice(from, 1); this.splice(to, 0, tmp); return this; }; proxyFn = function (obj, fn, args) { var fnUCase = fn.charAt(0).toUpperCase() + fn.slice(1), result; if (typeof obj['on' + fnUCase] === 'function') { if (obj['on' + fnUCase].apply(obj, args) === false) { return false; } } result = Array[fn].apply(obj, args); if (typeof result === 'undefined') { return true; } else { return result; } }; util.List.prototype.push = function () { return proxyFn(this, 'push', arguments); }; util.List.prototype.shift = function () { return proxyFn(this, 'shift', arguments); }; util.List.prototype.join = function () { return proxyFn(this, 'join', arguments); }; util.List.prototype.concat = function () { return proxyFn(this, 'concat', arguments); }; util.List.prototype.splice = function () { return proxyFn(this, 'splice', arguments); }; util.List.prototype.pop = function () { return proxyFn(this, 'pop', arguments); }; util.List.prototype.unshift = function () { return proxyFn(this, 'unshift', arguments); }; util.List.prototype.slice = function () { return proxyFn(this, 'slice', arguments); }; util.List.prototype.reverse = function () { return proxyFn(this, 'reverse', arguments); }; util.List.prototype.sort = function () { return proxyFn(this, 'sort', arguments); }Думал, после этого будет достаточно: var lst = new util.List(); lst.push(1); lst.push(2); lst.push(3);Но console.log(lst);не показывает никаких данных внутри объекта, кроме определённых выше функций. Вопрос: В JavaScript нельзя унаследовать массив? UPDATE: Ошибка была в строчке 41. Должно быть так: result = Array.prototype[fn].apply(obj, args); |
можно
|
Цитата:
Что такое: new lt.util.List(); |
Что такое List?
|
Цитата:
Цитата:
|
Цитата:
|
Цитата:
|
Цитата:
|
var A = function(){}; A.prototype = []; var a = new A; a.push('vasea', 'test'); alert(a); alert((Array.isArray || function(o){Object.prototype.toString.call(o) == '[object Array]'})(a)); В общем такое можно, но только в новых браузерах. IE<9 не проканает, хотя есть и свои хаки. |
Цитата:
Цитата:
Как пример: var list = new List(); list.onPush = function(data) { if (typeof data !== 'number') { return false; } return true; }Затем: list.push('строка'); // и эта строка не добавится list.push(777); // а с число - добавится list.push(function() {}); // и ничего кроме цифр туда не добавишь В результате в list должен добавиться только один элемент: list[0] == 777;Как-то так. Цитата:
|
Цитата:
|
inst,
а, да, щас сделаю))) я просто не понял что за лист я думал ты список какой то сделать хочешь. |
Цитата:
|
один вопрос - List должен фильтровать поступающие данные, если они назначаются так ?
myList[ 5 ] = "тут что-то"; |
Цитата:
|
Что хочу сказать, сделать такой List есть миллиард способов, ты хочешь сделать именно выбранным тобой способом?
То есть сделать обьект который бы использовал внутри себя массив и являлся для него как бы оболочкой. При том включал бы в себя все его методы, при том на все эти меоды можно было бы повесить фильтр типа onНазваниеМетода и если этот фильтр возвратит true, то метод срабатывал бы, если возвратит false , то не срабатывал бы)? так? |
Цитата:
if (list.hasOwnProperty(item)) {console.log(list[item])} } и при этом дополнительно имелся бы описанный тобой функционал фильтра. |
На самом деле, мне просто непонятно, что не так с моим кодом?
Но за помощь, конечно, всем большое спасибо :) |
Цитата:
|
Собираешься ли ты менять фильтры на ходу несколько раз, собираешься ли ты менять фильтры у отдельных листов? есть ли фильтры по умолчанию?
_ вот если бы мне нужен был массив который бы принимал только числа, я бы сделал не так тупо как ты я бы сделал так: |
Цитата:
А как? |
(function(name) { var prototype = {} prototype.__proto__ = Array.prototype; with (prototype) { // ниже перекрываешь методы добавляешь фильтры и.т.п. // раз перекрыли ------------------------------------------------------- push = function(arg) { if(typeof agr == 'string'){ //эта строчка использует метод массива Array.prototype.push.apply(this, arguments) } }; // два перекрыли ------------------------------------------------------- blablabla = function(arg) { alert(arg) }; } window[name] = function() { var list = [] list.__proto__ = prototype return list } })('List') новые листы создаются без new чтобы удобнее было, просто var list = List() |
В общем, суть та же, только для более узкого круга задач :)
Я разобрался, ошибка была в том, что я в proxyFn вместо result = Array.prototype[fn].apply(obj, args);вызывал метод не из прототипа. Спасибо за помощь :) |
Цитата:
|
inst,
Обратите внимание на splice, я не помню как именно, но метод работал не корректно, а может и не только он, то ли элементы не удалялись, то ли индексы не менялись, тоже как-то давно очень захотелось подобную штуку сделать, потом понял ,что затея вобщем-то, просто ради затеи... |
function List() { alert('Hello, I am List constructor!'); }; List.prototype = Object.create(Array.prototype, { move: { value: function () { alert('I am custom method "move"!'); } } }); new List().move(); |
>= IE9 и Опера 11.60, но если для себя то уже можно ж;)
|
Часовой пояс GMT +3, время: 10:41. |