Унаследовать 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, время: 17:07. |