Array Like Objects
Как правильно и дешево идентифицировать массиво-подообные объекты?
Очевидно, что следующей проверки мало:
var array = [1];
var arrayLike = {0:1, length:1};
var fakeArrayLike = {length:1, height:2};
var window = window;
var fn = function() {};
alert(isArrayLike(array)); // true
alert(isArrayLike(arrayLike)); // true
alert(isArrayLike(fakeArrayLike)); // true | must be false
alert(isArrayLike(window)); // true | must be false
alert(isArrayLike(fn)); // false | must be false
// -------------------
/**
* @param {*} any
* @returns {Boolean}
*/
function isArrayLike(any) {
return isObject(any) && any.hasOwnProperty('length');
}
/**
* @param {*} any
* @returns {Boolean}
*/
function isObject(any) {
return any !== null && typeof any === 'object';
}
Тут написано, что эти объекты должны иметь метод splice, но по факту они его не имеют:
var collection = document.getElementsByTagName('body');
alert(collection.splice);
alert(collection.length);
ангуляр
/**
* @private
* @param {*} obj
* @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments,
* String ...)
*/
function isArrayLike(obj) {
if (obj == null || isWindow(obj)) {
return false;
}
var length = obj.length;
if (obj.nodeType === 1 && length) {
return true;
}
return isString(obj) || isArray(obj) || length === 0 ||
typeof length === 'number' && length > 0 && (length - 1) in obj;
}
жуквери
function isArraylike( obj ) {
var length = obj.length,
type = jQuery.type( obj );
if ( type === "function" || jQuery.isWindow( obj ) ) {
return false;
}
if ( obj.nodeType === 1 && length ) {
return true;
}
return type === "array" || length === 0 ||
typeof length === "number" && length > 0 && ( length - 1 ) in obj;
}
Глядя на все это безобразие, кажется, что нет способа точно определить массиво-подобный объект. Так ли это? :) |
function likeArray(item) {
if( !('length' in item) ) return false;
for(var index = 0; index < item.length; index++){
if( !(index in item) ) return false;
}
return true;
}
:victory: илита |
Цитата:
|
Цитата:
к примеру arr = []; arr.length = 100; тоже не считается массивоподобным я осознанно это сделал хотя мог бы проверять чисто (item.length-1 in item) |
Цитата:
Symbol.iterator in object ? |
МаксимкаНевозбанный,
Цитата:
Цитата:
var object = {'12.24': 1, foo: NaN, length: 1};
alert(likeArray(object));
function likeArray(item) {
if( !('length' in item) ) return false;
var keys = Object.keys(item);
var indexCnt = 0;
for(var i = 0; i < keys.length; i++){
var key = keys[i]
if(+key != key) continue;
indexCnt++
}
return indexCnt === item.length;
}
|
Цитата:
alert(Symbol.iterator in document.getElementsByTagName('body'));
alert(Symbol.iterator in document.querySelectorAll('body'));
|
NodeList.prototype[Symbol.iterator] = function*() {
for (let i = 0; i < this.length; i++) {
yield this[i];
}
}
|
nerv_, я уже изменил свой камент) удаляй свой
|
function likeArray(item) {
if( item == null ) return false;
if( item === window ) return false;
if( !('length' in item) ) return false;
if( typeof item === 'function' ) return false;
if( item.length === 0 ) return true;
return ( item.length - 1 ) in item
}
вот самый крутой способ и самый быстрый |
Цитата:
var array = [1];
var arrayLike = {0:1, length:1};
var fakeArrayLike = {length:1, height:2};
var window = window;
var fn = function() {};
var fake1 = {foo: NaN, length: 1};
var fake2 = {'12.24': 1, length: 1};
var fake3 = '';
var fake4 = '1';
console.log(isArrayLike(document.getElementsByTagName('body')) === true, 1);
console.log(isArrayLike(document.querySelectorAll('body')) === true, 2);
console.log(isArrayLike(array) === true, 3);
console.log(isArrayLike(arrayLike) === true, 4);
console.log(isArrayLike(fakeArrayLike) === false, 5);
console.log(isArrayLike(window) === false, 6);
console.log(isArrayLike(fn) === false, 7);
console.log(isArrayLike(fake1) === false, 8);
console.log(isArrayLike(fake2) === false, 9);
console.log(isArrayLike(fake3) === false, 10);
console.log(isArrayLike(fake4) === false, 11);
function isArrayLike(item) {
if( typeof item === 'string' ) return false;
if( item == null ) return false;
if( item === window ) return false;
if( !('length' in item) ) return false;
if( typeof item === 'function' ) return false;
if( item.length === 0 ) return true;
return ( item.length - 1 ) in item
}
--- Erolast, не всегда есть возможность патчить) |
nerv_, а я вот думал на счет стринга но почему то оставил его, посмотрев на ангуляр, хотя нет в нем смысла
nerv_, ух ты, даже likeArray(document.createTextNode('выыв')) выдает false поставлю себе в юишку эту функцию ка я) |
Цитата:
Немного сократил. На последнем тесте врет. С этими не знаю как правильно. |
вообще likeArray предполагается что должна использоваться внутри toArray который по сути строку должен оборачивать в ['строка']
function toArray(item){
if( likeArray(item) ) return [].slice.call(item);
return [item]
}
так что строка не должна быть liteArray по уму чтобы можно было делать так eventNames = toArray(eventsNames) и если был массив строк то он и останется а если была строка то обернется в массив в котором будет в первой ячейке |
Цитата:
*** По поводу likeArray, то у меня юзается так: https://github.com/kobezzza/Collecti.../types.js#L134 Надо пожалуй добавить проверку для window. |
Цитата:
Ты в курсе, что все подобные проверки идут лесом ибо Цитата:
А еще зачем это, если есть старая добрая утиная типизация?) Т.е. эту функцию можно сократить. Впрочем, это поверхностное суждение, я не знаю как у тебя там все устроено) |
Цитата:
Цитата:
Я планировал вернуться к разработке новой версии Collection вскорем, проведу ревью кода, но думаю, что здесь так надо было. |
Цитата:
|
Цитата:
|
Цитата:
|
Цитата:
|
Цитата:
|
Цитата:
|
Цитата:
|
Цитата:
|
Ребят, годную книгу по паттернам архитектурного проганья не подскажете?
На какой digest свежечка стоит обратить внимание? А то я выпал на 3 месяца из жизни :) Спасибо. |
l-liava-l,
это подойдёт? http://largescalejs.ru/ |
Цитата:
|
kobezzza,
так "Банда четырёх" ещё старее, не?) |
Цитата:
Хотя есть Head First Паттерны проектирования по новее. |
Цитата:
Цитата:
Цитата:
|
Слушайте, а кто может мне объяснить, чем опасно для кросдоменной политики применение атрибута download? Вот что я имею в виду:
<a href="https://pp.vk.me/c411223/v411223005/2575/Cr9yOId2NPc.jpg" download="wow-pic.jpg">Картинка сохранится под оригинальным именем</a> Зачем это? |
Chrome не отправляет referrer, когда происходит клик по
<a download>, поэтому для ограничения доступа к ресурсам со сторонних сайтов придется выдумать что-то еще, кроме проверки referrer. |
Octane, так ограничения доступа же не происходит. И он начинает скачку, всё в порядке. Просто имя из атрибута download он не берёт.
|
Как считаете, что релизнется раньше - Халфа 3 или новая версия учебника javascript.ru?)
|
Цитата:
|
kobezzza,
лол:D |
Чет я сомневаюсь.
http://habrahabr.ru/post/255103/ |
Цитата:
К 2025 году чтобы все писали на языке программирования 1С:Предприятие |
Цитата:
http://bolgenos.ru/ Новейшая операционная система, разработанная талантливым программистом страны. Через 2 месяца он допишет всё необходимое ПО страны! |
| Часовой пояс GMT +3, время: 18:50. |