Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   DOMNodeList to Array (https://javascript.ru/forum/misc/1620-domnodelist-array.html)

Octane 24.08.2008 23:40

DOMNodeList to Array
 
Возможно ли выполнить подобное в IE:
var array = [].slice.call(document.body.childNodes);


Странно, почему же тогда код успешно выполняется и в IE с «arguments», который тоже не является «Array»?
(function(a, b, c) {
	alert([].slice.call(arguments).length);
})(1, 2, 3);

Kolyaj 25.08.2008 09:29

Ну arguments, как минимум, является объектом JScript, а DOMNodeList -- объектом DOM.

ZoNT 25.08.2008 12:46

Цитата:

Сообщение от Octane (Сообщение 4937)
Возможно ли выполнить подобное в IE:
var array = [].slice.call(document.body.childNodes);


Странно, почему же тогда код успешно выполняется и в IE с «arguments», который тоже не является «Array»?
(function(a, b, c) {
	alert([].slice.call(arguments).length);
})(1, 2, 3);

И что тут удивительного?
Ты вызываешь метод slice пустого массива, передаёшь (смотри формат комманды call) ему arguments, а сартИндекс и ЭндИндекс не передаёшь, соответственно он возвращает НОВЫЙ массив со всеми элементами (с первого по последний), что были в arguments.

Kolyaj 25.08.2008 12:55

ZoNT, вопрос не в том, почему работает с arguments, а в том, почему не работает с DOMNodeList.

ZoNT 25.08.2008 12:57

потому что аргументс - это почти массив, а домлист - это дом лист...

Kolyaj 25.08.2008 13:00

Оригинальный ответ :) Следовательно, во всех браузерах, кроме ИЕ, DOMNodeList -- это почти массив.

З.Ы. Что за нечеткая логика? Объект или является массивом, или не является, третьего не дано. Ни arguments, ни DOMNodeList массивами не являются.

ZoNT 25.08.2008 13:03

Он не является нигде, просто некоторые браузеры работают с ним по-разному и всё...
Это как парсинг даты: можно написать чтобы он жрал некорректные строки, а можно чётко придерживаться стандарта...

Kolyaj 25.08.2008 13:33

Цитата:

Сообщение от ZoNT
Он не является нигде

Если бы DOMNodeList являлся массивом, темы бы не было. Вопрос в том, как преобразовать коллекцию в массив без перебора элементов.

ZoNT 25.08.2008 13:34

я подумаю :)
Ни разу таким вопросом не задавался...

А оно надо? Помоему перебор - тоже неплохо... А нестандартный способ будет наверняка не быстрее...

Octane 25.08.2008 16:07

Цитата:

Сообщение от ZoNT (Сообщение 4949)
смотри формат комманды call

Работает же везде без остальных параметров... а в IE ни с параметрами, ни без них, ни с «apply» — вообще никак :(

Цитата:

Сообщение от ZoNT (Сообщение 4949)
А оно надо? Помоему перебор - тоже неплохо...

«Перебор» — пользовательская функции, мне кажется «slice» будет быстрее :) А вообще было бы удобно реализовать такую возможность, чтобы не писать отдельную функцию для перевода «DOMNodeList» в «Array», когда требуются методы работы с «Array», например «push». :cool:

p.s. в «jQuery» есть метод «makeArray» (v.1.2.6, line 1129):
makeArray: function( array ) {
		var ret = [];

		if( array != null ){
			var i = array.length;
			//the window, strings and functions also have 'length'
			if( i == null || array.split || array.setInterval || array.call )
				ret[0] = array;
			else
				while( i )
					ret[--i] = array[i];
		}

		return ret;
	},

Реализовано перебором, правда каким-то извращенным... Интересно, они не догадались про «slice» или не используют его, потому что не возможно заставить работать в IE? :rolleyes:

p.p.s. не зря, наверное, придумали «makeArray» в «jQuery», значит нужная функция.

ZoNT 25.08.2008 16:15

Это очень редкие случаи и это усложнит интерпретатор джаваскрипта...
Получится эволюция в сторону увеличения уровня языка: на ассемблере можно сделать всё и это будет работать ахриненно быстро, но ВСЁ придётся реализовывать самому, так как есть только простейшие команды. По мере навешивания высокоуровневого функционала становиться проще разрабатвывать программы, но высокоуровневые языки трудно переносимы, ограничены функционально, размер кода (готового) раздувается. Не факт, что реализация функционала самая оптимальная (ты не знаешь, так как это делал какой-то дядя, а не ты руками).

интерпретатору проще и быстрее обработать 10 команд (если их будет всего допустим 50 простых), чем обработать 3, но если придётся выбирать из 300 и они будет сложные и редкоиспользуемые...

Kolyaj 25.08.2008 16:27

Octane, вы аккуратнее у jQuery списывайте, там местами такой бред написан.

Octane 25.08.2008 18:04

Наоборот, стараюсь не списывать, а написать сам и найти более короткое решение :)

ZoNT 25.08.2008 18:48

в компилируемых языках более корткое - не значит более быстродействующее :)

Ну а в интерепретируемых конечно лучше стремиться к уменьшению количества кода...

Octane 23.12.2008 22:40

И опять makeArray :)

Доступна новая версия jQuery 1.3b1, в ней метод makeArray притерпел некоторые изменения и стал выглядеть следующим образом:
var makeArray = function(array, results) {
	array = Array.prototype.slice.call( array );

	if ( results ) {
		results.push.apply( results, array );
		return results;
	}
	
	return array;
};

// Perform a simple check to determine if the browser is capable of
// converting a NodeList to an array using builtin methods.
try {
	Array.prototype.slice.call( document.documentElement.childNodes );

// Provide a fallback method if it does not work
} catch(e){
	makeArray = function(array, results) {
		var ret = results || [];

		if ( array instanceof Array ) {
			Array.prototype.push.apply( ret, array );
		} else {
			if ( typeof array.length === "number" ) {
				for ( var i = 0, l = array.length; i < l; i++ ) {
					ret.push( array[i] );
				}
			} else {
				for ( var i = 0; array[i]; i++ ) {
					ret.push( array[i] );
				}
			}
		}

		return ret;
	};
}


То есть они проверяют не IE это или другой браузер, а возможность выполнить:
Array.prototype.slice.call( document.documentElement.childNodes );

Может ли это значить, что есть еще браузеры, кроме IE, которые будут выдавать ошибку при таком способе?

Kolyaj 23.12.2008 23:39

Проверять надо не браузер, а наличие доступной функции в нем.

Цитата:

Сообщение от Octane
Может ли это значить, что есть еще браузеры, кроме IE, которые будут выдавать ошибку при таком способе?

Это значит, что данный код будет работать в любом браузере, независимо от его UserAgent'а.


Часовой пояс GMT +3, время: 13:37.