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, время: 16:30. |