Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   Библиотечка . (https://javascript.ru/forum/project/6025-bibliotechka.html)

Riim 22.08.2011 16:30

Еще маленькая ошибка (сам только что у себя заметил):
var r = (new Array(5)).map(function(I, i) {
	return i;
});
alert(r.length);


Выводит "0", при нативной реализации выводит "5".

Ну и проверки на (forEach, map, filter, every, some) и (reduce, reduceRight), возможно, достаточно делать по одной на всех:
if (!('forEach' in arrayProto)) {
	arrayProto.forEach = function() {/* ..... */};
	arrayProto.map = function() {/* ..... */};
	arrayProto.filter = function() {/* ..... */};
	arrayProto.every = function() {/* ..... */};
	arrayProto.some = function() {/* ..... */};
}

if (!('reduce' in arrayProto)) {
	arrayProto.reduce = function() {/* ..... */};
	arrayProto.reduceRight = function() {/* ..... */};
}

Kolyaj 22.08.2011 16:44

Цитата:

Сообщение от Riim
Еще маленькая ошибка (сам только что у себя заметил):

Интересный кейс, спасибо. А как ты такое у себя получил?


Цитата:

Сообщение от Riim
Ну и проверки на (forEach, map, filter, every, some) и (reduce, reduceRight), возможно, достаточно делать по одной на всех:

Я думал над этим, чем-то мне такая проверка не нравится :)

Riim 22.08.2011 16:55

Цитата:

Сообщение от Kolyaj
А как ты такое у себя получил?

как заметил? Пытаюсь придумать как обходиться без Array.range , хотя бы в простейших случаях, и не писать:
var range = [], i = 10;
while (i) {
    range[--i] = i + 1;
}
alert(range);

хотя и так нормально, в общем вечер свободный, вот и маюсь.

Kolyaj 22.08.2011 16:58

А чем Array.range не угодил? Он же для перебора чисел по порядку и придуман.

Riim 22.08.2011 17:10

Цитата:

Сообщение от Kolyaj
А чем Array.range не угодил?

хочу оставить самое необходимое.

float 31.08.2011 17:29

Цитата:

Интересный кейс, спасибо.
А править этот момент собираетесь? Я просто тоже юзаю подобные функции для совместимости со старыми браузерами...
Может убрать if(a in array)? Что-то ща пытаюсь представить зачем эта проверка нужна, чет туго.

Kolyaj 31.08.2011 17:51

Пару часов назад запушил исправленную версию.

Цитата:

Сообщение от float
Что-то ща пытаюсь представить зачем эта проверка нужна, чет туго.

Проверка на существование в массиве элемента с данным индексом.

float 31.08.2011 18:54

Цитата:

Проверка на существование в массиве элемента с данным индексом.
так в пределах i он вроде как существует всегда, только не назначено значение...

var t = new Array(5);
alert(t.length+'\n'+t[0]);

var t = [];
t[0] = 1;
t[100] =1;
t.length


Стандартным методам походу плевать undefined там или что другое...

var r = new Array(5);
r[2] = 1;
var t = r.map(function(c, i, m) {
    return ++m[i];
})
t.length // стандарт 5, с проверкой 3


Цитата:

Пару часов назад запушил исправленную версию.
Ща гляну.

Sweet 31.08.2011 19:08

Цитата:

Сообщение от float
так в пределах i он вроде как существует всегда, только не назначено значение...

Ну по такой логике в пределах еще и "vasyaPupkin" всенда существует, но его значение не определено:
var t = new Array(5);
alert(t.length+'\n'+t["vasyaPupkin"]);

float 31.08.2011 19:17

всё я догнал зачем такие сложности.
Стандартная функция не вызывает fn если элемент undefined.
var t = new Array(5);
t[1] = 1;
t.map(function(c, i) {alert(i); return 2;});

float 31.08.2011 19:23

кстати прикольно пофиксили:)
Цитата:

Ну по такой логике в пределах еще и "vasyaPupkin" всенда существует, но его значение не определено
я отталкивался от предположения, что массив это участок в памяти, а new Array(n) его выделяет. В вашем случае компилятор просто возвращает тот же undefined, хотя выделения памяти под него небыло и оно не было объявлено.
Так что с точки зрения железа вроде это 2 разных undefined. Может я в чём-то неправ?

Sweet 31.08.2011 19:23

Цитата:

Сообщение от float
Стандартная функция не вызывает fn если элемент undefined.

Вызывает, если элемент undefined, но свойство с таким индексом есть:
var t = new Array(5);
t[1] = undefined;
t.map(function(c, i) {alert(c); return 2;});

Sweet 31.08.2011 19:26

Цитата:

Сообщение от float
я отталкивался от предположения, что массив это участок в памяти, а new Array(n) его выделяет. В вашем случае компилятор просто возвращает тот же undefined, хотя св-во не объявлено и выделения памяти под него небыло.

Лучше отталкиваться от предположения, что Array - это обычный объект. Только у него есть сеттер на добавление индексов, чтобы менять свойство length.

float 31.08.2011 19:34

Цитата:

Лучше отталкиваться от предположения, что Array - это обычный объект. Только у него есть сеттер на добавление индексов, чтобы менять свойство length.
хм... учтёмс:)

float 31.08.2011 19:43

У меня кстати есть предложение по сжиманию кода. Я у себя делаю так:
(function(A) {

})(Array.prototype);


Имхо коротко и понятно:)
Хотя в вашем случае это будет не так красиво, зачем-то ещё Array передаёте...

Octane 31.08.2011 20:01

Цитата:

Сообщение от float
зачем-то ещё Array передаёте...

isArray не в прототипе

Kolyaj 31.08.2011 20:14

Цитата:

Сообщение от float
я отталкивался от предположения, что массив это участок в памяти, а new Array(n) его выделяет.

В JavaScript массив это обычный объект, у которого переопределён внутренний метод [[Set]], который следит за свойством length и за числовыми свойствами.

Правила такие
При установке свойства length удаляются числовые свойства больше либо равные новому length.
При установке числового свойства, если length не больше этого свойства, то length устанавливается на единицу больше этого свойства.
Отрицательный length, кстати, присвоить нельзя.

Некоторые следствия из этих правил.
Свойство length равно количеству элементов в массиве только при аккуратной работе с массивом (нет пропусков элементов). В общем случае length всегда больше максимального индекса в массиве.
Чтобы очистить массив, достаточно свойству length присвоить 0.

float 31.08.2011 21:22

Цитата:

При установке свойства length
перепроверил даже. блин глазам не верю:). всегда считал length рид онли... бывает же такое.
Да... я уже понял, что рассматривать низкий уровень в js-се не катит, тк его движки сами написаны на ОО язке/ах...
Kolyaj, сенкс за доходчивое объяснение.
Наверное надо всё таки собраться и прочитать http://javascript.ru/ecma/part15 :)

Octane 02.09.2011 22:27

Переопределенные constructor, toString, toLocaleString, valueOf, hasOwnProperty, propertyIsEnumerable и isPrototypeOf не становятся enumerable в IE<9, поэтому Object.keys({toString: fn}) вернет пустой массив.
Думаю toString и valueOf хорошо бы пофиксить.

___________________
offtop
Раньше этого как-то не замечал, а вот сейчас наткнулся, такое во всех браузерах:
function F() {}
F.prototype.constructor = F;
F.prototype.toString = F;

for (var key in new F) {
    alert(key);
}
constructor не становится enumerable, в отличие от toString

Kolyaj 02.09.2011 22:52

Цитата:

Сообщение от Octane
Переопределенные constructor, toString, toLocaleString, valueOf, hasOwnProperty, propertyIsEnumerable и isPrototypeOf не становятся enumerable в IE<9, поэтому Object.keys({toString: fn}) вернет пустой массив.

О, спасибо за список. Давно хочу этим заняться, но пока только toString в Object.mixin пофиксил.


Цитата:

Сообщение от Octane
constructor не становится enumerable, в отличие от toString

Потому что constructor переопределяется, а toString создаётся.
function F() {}
alert([F.prototype.hasOwnProperty('constructor'), F.prototype.hasOwnProperty('toString')])

Octane 03.09.2011 16:42

О сейчас в голову пришло, с таким фиксом теоретически возникнет проблема с defineProperty:
(function () {

	function fn() {}

	var obj = {};
	Object.defineProperty(obj, "toString", {value: fn, enumerable: false});

	console.log(Object.keys(obj));//[]
	console.log(obj.hasOwnProperty("toString"));//true
	console.log(obj.propertyIsEnumerable("toString"));//false

}());

кто-то специально выставит enumerable:false, а мы в Object.keys проверим obj.hasOwnProperty("toString") и все равно вернем ключ toString. НО браузеров, одновременно поддерживающих Object.defindeProperty и не поддерживающих Object.keys, и имеющих баг, наверное нет, ну кроме IE8, но в нем Object.defindeProperty работает только для DOM-объектов и при попытке установить для этих свойств enumerable:false возникает ошибка: «Для данного объекта атрибут enumerable дескриптора свойства не может иметь значение false»
Object.defineProperty(Element.prototype, "toString", {
	value: function fn() {},
	enumerable: false
});


Object.keys: 1|2

float 05.09.2011 19:04

Вроде ерунда, но советую переписать Array_prototype.flatten. Медленно работает.

Kolyaj 06.09.2011 00:01

Медленно по сравнению с чем?

Я его из Prototype перетащил, не помню, чтобы использовал :)

float 06.09.2011 01:16

Цитата:

Я его из Prototype перетащил, не помню, чтобы использовал
хотя конечно, да... функция специфическая.
в своем ворке юзаю похожую функцию для разворачивания мультивыборок.

Riim 06.09.2011 01:40

Я в своем Array#flatten вместо проверки на массив делал проверку на наличие метода flatten:
'flatten' in Object(value)

так вреде правильней (вдруг флаттиться выравниваться умеют не только массивы), хотя хз.

Riim 16.09.2011 02:54

Еще улучшение заметил: в Array#remove к вызову indexOf полезно добавить index вторым аргументом (даже если собственная реализация Array#indexOf не поддерживает второй аргумент, чаще нативная будет использоваться). Так массив не будет каждый раз сначала перебираться.

x-yuri 03.05.2012 20:32

А чего ты тег экранируешь, а имя класса не экранируешь? Хотя там по-моему вообще экранировать не надо, да и trim в общем-то...

А еще можно добавить проверку, что селектор указан, чтобы не делать таке проверки за пределами функции

FINoM 04.05.2012 18:37

Цитата:

Сообщение от x-yuri
А чего ты тег экранируешь, а имя класса не экранируешь?

Да и вообще строка интересная, чего бы просто не написать tagName !== '*'


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