27.03.2013, 12:42
|
|
Профессор
|
|
Регистрация: 11.09.2010
Сообщений: 8,804
|
|
Как создать массив с особым прототипом?
Нужно создать массив со своим кастомным прототипом.
Если в браузере доступно свойство __proto__, то можно сделать так:
function MyArray () {
var instance = []
instance.__proto__ = arguments.callee.prototype
return instance
}
MyArray.prototype.myFunction = function () {}
var myArray = new MyArray()
alert( typeof myArray.myFunction )
А как сделать такое же без __proto__ ?
Последний раз редактировалось danik.js, 27.03.2013 в 13:53.
|
|
27.03.2013, 13:27
|
|
Тлен
|
|
Регистрация: 02.01.2010
Сообщений: 6,590
|
|
Мб так:
function MyArray () {}
MyArray.prototype = Array.prototype;
MyArray.prototype.myFunction = function () {
return this[0] + this[1]
}
var myArray = new MyArray()
alert([
typeof myArray.myFunction,
myArray instanceof Array,
typeof myArray
])
myArray.push(5)
myArray.push(3)
alert([
myArray.length,
myArray.myFunction()
])
...но зачем?
__________________
29375, 35
|
|
27.03.2013, 13:51
|
|
Профессор
|
|
Регистрация: 11.09.2010
Сообщений: 8,804
|
|
Aetae
function MyArray () {}
MyArray.prototype = Array.prototype;
MyArray.prototype.myFunction = function () {
return this[0] + this[1]
}
var myArray = new MyArray()
// во-первых мы изменили прототип Array, но это решаемо
alert( typeof [].myFunction )
// во-вторых, мы получили таки объект, а не массив
alert( Array.isArray(myArray) )
alert( Object.prototype.toString.call(myArray) )
А должно быть так:
function MyArray () {
var instance = []
instance.__proto__ = arguments.callee.prototype
return instance
}
MyArray.prototype.myFunction = function () {}
var myArray = new MyArray()
alert( typeof [].myFunction )
alert( Array.isArray(myArray) )
alert( Object.prototype.toString.call(myArray) )
Зачем это? Пытаюсь заставить библиотеку Zepto работать с IE. А там как раз использется массив, а не объект.
Да и вообще интересно - возможно ли так сделать без __proto__
|
|
27.03.2013, 14:11
|
|
Профессор
|
|
Регистрация: 28.02.2011
Сообщений: 349
|
|
var MyArray = function() {
var _myPrototype = {
joinReverse : function(s) { return this.slice(0).reverse().join(s); }
}
return function() {
var ret = Array.apply( null, arguments );
for( var i in _myPrototype )
// if( typeof _myPrototype[i] == "function" )
ret[i] = _myPrototype[i];
return ret;
}
}();
var test = MyArray( 1, "bb", 333 );
alert( test.joinReverse( " - " ) );
|
|
27.03.2013, 14:15
|
|
Тлен
|
|
Регистрация: 02.01.2010
Сообщений: 6,590
|
|
Сообщение от danik.js
|
// во-первых мы изменили прототип Array, но это решаемо
|
Эт да, бывает)
Сообщение от danik.js
|
Зачем это? Пытаюсь заставить библиотеку Zepto работать с IE. А там как раз использется массив, а не объект.
|
Лол, Zepto прямо позиционируется как jquery без ie.) Хочешь поддержку ie - откатись на jquery. (Там так и написано на главной: "If you need to support Internet Explorer, you can fall back on jQuery.")
Сообщение от danik.js
|
Да и вообще интересно - возможно ли так сделать без __proto__
|
Можно сделать без __proto__ - используюя новомодные методы Object(которые в ie конечно не работают). =)
Ну или вручную навешивать на каждый создаваемый массив методы, что, естесно, скажется на производительности и будет вылезать в for in.
...upd: пока писал - последний вариант реализовал rgl.)
__________________
29375, 35
|
|
27.03.2013, 16:21
|
|
Профессор
|
|
Регистрация: 18.01.2013
Сообщений: 1,098
|
|
function MEGAArray (){};
MEGAArray.prototype = new Array;
MEGAArray.prototype.godOfJavascript = function(){};
Прототипное наследование не, не слышали?
Последний раз редактировалось megaupload, 27.03.2013 в 17:22.
|
|
27.03.2013, 17:40
|
|
Профессор
|
|
Регистрация: 28.02.2011
Сообщений: 349
|
|
Сообщение от megaupload
|
function MEGAArray (){};
MEGAArray.prototype = new Array;
MEGAArray.prototype.godOfJavascript = function(){};
Прототипное наследование не, не слышали?
|
Разумеется, это первое, что приходит в голову каждому, знающему JavaScript на более-менее нормальном уровне. Но каждый (м-м-м, почти каждый) прежде чем писать в форуме, проверил, и убедился что это не работает. Дело в том, что у полученного объекта отсутствует свойство length (точнее оно присутствует, но не свое, а наследуемое, а там оно ноль). Из-за этого методы массива не работают. Свойство length можно добавить, но оно не будет автоматически модифицироваться как должно у массива.
function MEGAArray (){};
MEGAArray.prototype = new Array;
var test = new MEGAArray();
test[0] = "a";
test[1] = "bb";
test[2] = "ccc";
alert( test.length );
|
|
27.03.2013, 17:48
|
|
Профессор
|
|
Регистрация: 28.02.2011
Сообщений: 349
|
|
Сообщение от Aetae
|
Ну или вручную навешивать на каждый создаваемый массив методы, что, естесно, скажется на производительности и будет вылезать в for in.
|
Как это скажется на производительности, не знаю, но думаю что сильно не ухудшит, т.к. добавленные методы будут находиться ближе, прямо тут а не по цепочке. Другое дело, наверно памяти больше займет. А вылезать в for in будет в любом случае, и если в прототип добавить тоже.
Последний раз редактировалось rgl, 27.03.2013 в 18:26.
|
|
27.03.2013, 18:45
|
|
Профессор
|
|
Регистрация: 11.09.2010
Сообщений: 8,804
|
|
rgl, твой вариант некудышный, ибо методов много, а конструктор вызывается часто. Так что думаю потребление ресурсов возрастет ощутимо. Кроме того, прототипа то и нет получается ). А нужно чтобы был прототип. И добавляя метод в прототип мы автоматом получаем его у уже созданных экземпляров.
megaupload, этот вариант я пробовал. В консоли объект действительно выглядит как [массив], вот только Array.isArray не обманешь. Ну и toString также выдает [object Object]
А то, что length не обновляется - это не беда. Работа с коллекцией всеравно идет через методы, а не напрямую.
Сообщение от Aetae
|
Лол, Zepto прямо позиционируется как jquery без ie.) Хочешь поддержку ie - откатись на jquery. (Там так и написано на главной: "If you need to support Internet Explorer, you can fall back on jQuery.")
|
Дело в том, что это по большей части касается IE6-8.
В девятке и уж тем более в десятке есть все, что нужно. Так что отсутствие поддержки IE9-10 - это всего лишь наследие zepto. А корень проблемы в использовании __proto__ . Кстати, кто-то говорил что это свойство добавили в стандарт, это так?
Если заглянуть сюда https://github.com/madrobby/zepto/issues/ то видно, что не я один хочу поддержки IE.
Сообщение от Aetae
|
используюя новомодные методы Object
|
Че за методы такие?
|
|
27.03.2013, 19:21
|
|
Профессор
|
|
Регистрация: 18.01.2013
Сообщений: 1,098
|
|
function MyArray() {}
MyArray.prototype = [];
MyArray.prototype.toString = function(){alert('ну вы нубы')};
var q = new MyArray();
q.push(1);
q.push(1);
alert(q.length);
q+"";
Последний раз редактировалось megaupload, 27.03.2013 в 19:25.
|
|
|
|