Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 27.03.2013, 12:42
Аватар для danik.js
Профессор
Отправить личное сообщение для danik.js Посмотреть профиль Найти все сообщения от danik.js
 
Регистрация: 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.
Ответить с цитированием
  #2 (permalink)  
Старый 27.03.2013, 13:27
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,495

Мб так:
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
Ответить с цитированием
  #3 (permalink)  
Старый 27.03.2013, 13:51
Аватар для danik.js
Профессор
Отправить личное сообщение для danik.js Посмотреть профиль Найти все сообщения от danik.js
 
Регистрация: 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__
Ответить с цитированием
  #4 (permalink)  
Старый 27.03.2013, 14:11
Аватар для rgl
rgl rgl вне форума
Профессор
Отправить личное сообщение для rgl Посмотреть профиль Найти все сообщения от rgl
 
Регистрация: 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( " - " ) );
Ответить с цитированием
  #5 (permalink)  
Старый 27.03.2013, 14:15
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,495

Сообщение от 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
Ответить с цитированием
  #6 (permalink)  
Старый 27.03.2013, 16:21
Аватар для megaupload
Профессор
Отправить личное сообщение для megaupload Посмотреть профиль Найти все сообщения от megaupload
 
Регистрация: 18.01.2013
Сообщений: 1,098

function MEGAArray (){};
MEGAArray.prototype = new Array;

MEGAArray.prototype.godOfJavascript = function(){};


Прототипное наследование не, не слышали?

Последний раз редактировалось megaupload, 27.03.2013 в 17:22.
Ответить с цитированием
  #7 (permalink)  
Старый 27.03.2013, 17:40
Аватар для rgl
rgl rgl вне форума
Профессор
Отправить личное сообщение для rgl Посмотреть профиль Найти все сообщения от rgl
 
Регистрация: 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 );
Ответить с цитированием
  #8 (permalink)  
Старый 27.03.2013, 17:48
Аватар для rgl
rgl rgl вне форума
Профессор
Отправить личное сообщение для rgl Посмотреть профиль Найти все сообщения от rgl
 
Регистрация: 28.02.2011
Сообщений: 349

Сообщение от Aetae Посмотреть сообщение
Ну или вручную навешивать на каждый создаваемый массив методы, что, естесно, скажется на производительности и будет вылезать в for in.
Как это скажется на производительности, не знаю, но думаю что сильно не ухудшит, т.к. добавленные методы будут находиться ближе, прямо тут а не по цепочке. Другое дело, наверно памяти больше займет. А вылезать в for in будет в любом случае, и если в прототип добавить тоже.

Последний раз редактировалось rgl, 27.03.2013 в 18:26.
Ответить с цитированием
  #9 (permalink)  
Старый 27.03.2013, 18:45
Аватар для danik.js
Профессор
Отправить личное сообщение для danik.js Посмотреть профиль Найти все сообщения от danik.js
 
Регистрация: 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
Че за методы такие?
Ответить с цитированием
  #10 (permalink)  
Старый 27.03.2013, 19:21
Аватар для megaupload
Профессор
Отправить личное сообщение для megaupload Посмотреть профиль Найти все сообщения от megaupload
 
Регистрация: 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.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Создать массив функций (?) venzh jQuery 1 02.02.2012 06:11
Как создать массив из картинок KamalovRadik Firefox/Mozilla 17 04.10.2011 14:06
Создать массив не содержащие данные другого масива KamalovRadik Общие вопросы Javascript 1 05.09.2011 03:30
Подскажите код как создать эффект... lopraeph Элементы интерфейса 1 09.06.2011 20:18
как создать елемент с вложеными елементами scuter Events/DOM/Window 11 14.05.2008 16:15