Комментарии 81
Жаль, что много неверных и спорных сниппетов. Pull'ить и pull'ить :)
+2
НЛО прилетело и опубликовало эту надпись здесь
некоторые так вообще запредельный ****ец
+3
НЛО прилетело и опубликовало эту надпись здесь
Начало положено? Да там надо 80 удалить и написать иначе.
+2
НЛО прилетело и опубликовало эту надпись здесь
Главная проблема, что, при желании изменить, под каждым из пунктов затянется холивар на 200 комментов да ещё и на английском языке. У меня нет сил на такое.
+2
Да, собеседование не прошел бы…
+2
jQuery сам по себе один большой антипаттерн.
-5
НЛО прилетело и опубликовало эту надпись здесь
Интерпретатор попытается привести document.attachEvent к типу Boolean. Так можно, но это не нужно, лишняя операция.
0
Все заблуждаются. Есть огромное количество «правильных» способов. Например:
if ('attachEvent' in document) // это явно лучше, чем глупая проверка на undefined
if (document.attachEvent == null) // или вот так можно
if (typeof document.attachEvent == 'function') // нам ведь нужна именно функция, да?
+2
Крокфорд рекомендует глупую проверку на undefined или hasOwnProperty() вместо 'in'
0
И что? У Крокфорда, при всём моём уважении к нему, куча заблуждений и «пунктиков».
Хотя бы один аргумент, почему
Хотя бы один аргумент, почему
document.attachEvent
надо проверять на undefined, а не на function? Чем проверка на undefined лучше, чем сравнение с null? И так далее.+1
тем, что паттерны и стандарты хороши не тем, что они чем-то лучше других, а тем, что они стандарты :)
-1
Чем проверка на typeof == undefined стандартнее проверки на равенство null? В том же jQuery чаще проверяется именно на равенство с null
+2
Мы проверяем существует ли свойство или нет (то есть undefined). Мне кажется куда логичнее проверять на undefined путём сравнения с undefined, хотя сравнение с приведением типов с null тоже в данном случае сработает.
0
Нет, вы проверяете свойство на неопределённость и только то, что при обращении к несуществующим свойствам вы получаете undefined, а не exception даёт вам инструмент. Сам факт наличия свойства можно проверить одним из методов — через hasOwnProperty для собственных свойств и in для всего прототипа.
(function (undefined) {
var object = { foo: undefined };
console.log( typeof object.foo != 'undefined' ); // false - свойства нету? О.о
console.log( 'foo' in object ); // true - есть
console.log( {}.hasOwnProperty.call( object, 'foo' ) ); // true
})();
+1
хотя сравнение с приведением типов с null тоже в данном случае сработает.
Это не «сравнение с приведением типов», это «нестрогое сравнение». Вполне возможно, что именно этот случай оптимизирован и очень быстр:
м
operator equals (left, right) {
if ( (isNull(left ) || isUndefined(left )) &&
(isNull(right) || isUndefined(right))) {
return true;
}
// тут проверяем типы и так далее
}
Так что аргумент «мне кажется, что такой способ быстрее» — это вилами по воде.
0
я не приводил этот аргумент, более того в соседней ветке заявил, что в данном контексте, он по моему мнению абсолютно бессмысленен
0
НЛО прилетело и опубликовало эту надпись здесь
Если заранее известен конкретный тип (function), то, конечно, лучше проверять сразу на него.
0
ну и чёткое сравнение с undefined на 0,0001% теоретически лучше чем сравнение с приведением типа с null, 0 или пустой строкой (непомню уже, пустая строка false?)
0
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Рекомендуется он в соответствии с теорией, что сравнение без приведения типов (== vs ===) чуть быстрее по скорости.
Теория ошибочна. Приведение типов не происходит, если обе стороны выражения — одного типа. Так что сравнивать string со string можно одинаково что двойным, что тройным равно.
0
Лишняя операция в document.attachEvent == null, это полностью аналогично такому коду
Лишний вызов typeof и создание лишней строки
А такой вариант интересный, никогда не использовал.
if(!!null === !!document.attachEvent) ... // !! - самый короткий путь приведения к boolean
Лишний вызов typeof и создание лишней строки
if (typeof document.attachEvent == 'function')
А такой вариант интересный, никогда не использовал.
if ('attachEvent' in document)
0
Вряд ли на каждый вызов typeof создается новая строка, скорее всего там используются константы.
0
Лишняя операция в document.attachEvent == null, это полностью аналогично такому коду
if(!!null === !!document.attachEvent)
Заблуждение на заблуждении) Вот пруф, что это не так:
(function () {
var document = { attachEvent: false };
console.log( document.attachEvent == null ); // false
console.log( !!document.attachEvent == !!null ); // true
})();
0
Ну… мой вариант полностью рабочий.
А этот код ваш, я его не проверял.
Т.е. вы написали неверный код, который я попытался привести к верному аналогу, но он не заработал, т.к. изначально были неверные данные.
console.log( !!document.attachEvent === !!null );
А этот код ваш, я его не проверял.
if (document.attachEvent == null) // или вот так можно
Т.е. вы написали неверный код, который я попытался привести к верному аналогу, но он не заработал, т.к. изначально были неверные данные.
0
Не знаю почему true всегда, я null почти никогда не использовал.
var document = { attachEvent: false };
console.log( document.attachEvent == null ); // true
console.log( document.attachEvent1 == null ); // true
0
Все, я запутался… %) Выхожу из боя…
document = { attachEvent: false };
console.log( !!document.attachEvent === !!null ); // true
console.log( !!document.attachEvent1 === !!null ); // true
0
Зачем вы меня дурите?
![](https://habrastorage.org/r/w1560/storage2/22e/4ab/61a/22e4ab61ab4fc0b17f21c089a0aaf811.png)
![](https://habrastorage.org/storage2/22e/4ab/61a/22e4ab61ab4fc0b17f21c089a0aaf811.png)
0
Извиняюсь, обрезать нечем.
xmages.net/storage/10/1/0/e/6/upload/83278187.png
P.S. Оффтоп. Есть сервис для заливки, без регистрации и сразу сделать crop?
xmages.net/storage/10/1/0/e/6/upload/83278187.png
P.S. Оффтоп. Есть сервис для заливки, без регистрации и сразу сделать crop?
0
Тут кажется оберка сыграла роль, с ней у меня также… document кажется нельзя переопределить, не знал об этом.
0
Глобальный
document
не переопределяется. Если сделаете console.log( document )
, то поймёте в чём ваша ошибка. Я не зря оборачиваю код в анонимную функцию0
Мне казалось в JS переопределяется все и везде. Это скорей всего ограничение браузера, в спецификациях нет глобальных переменных window и document.
0
Это API. Вполне возможно, что согласно API document определяется как-то так:
Тогда переопределить его будет нельзя:
Моё предположение подтверждается этим:
Object.defineProperty( window, 'document', {
configurable: false,
value: new Document()
});
Тогда переопределить его будет нельзя:
(function () {
var obj = {};
Object.defineProperty( obj, 'test', { configurable: false, value: 1 });
obj.test = 2;
console.log( obj.test ); // 1
}());
(function () {
'use strict';
var obj = {};
Object.defineProperty( obj, 'test', { configurable: false, value: 1 });
obj.test = 2;
console.log( obj.test );
// Cannot assign to read only property 'test' of #<Object>
}());
Моё предположение подтверждается этим:
(function () {
'use strict';
window.document = 1;
// Cannot assign to read only property 'document' of [object DOMWindow]
}());
0
w3c: www.w3.org/TR/Window/#dfn-window-interface
ну и в html5-главах тоже расписана структура объекта window, причём куда более подробно и конкретно.
ну и в html5-главах тоже расписана структура объекта window, причём куда более подробно и конкретно.
0
Логично предположить, что каст стоит дороже, чем получение типа.
А оператор in не обходит ли все свойства объекта, чтобы понять есть ли в нем указанное свойство?
Второе опять же каст. Третье согласен можно и так.
А оператор in не обходит ли все свойства объекта, чтобы понять есть ли в нем указанное свойство?
Второе опять же каст. Третье согласен можно и так.
0
Ну вот все эти размышления что тут стоит дороже и есть основной антипаттерн )
0
Ну я лишь пытаюсь обосновать выбор именно того средства. А когда делаешь паттерн, то вполне логично использовать максимально быстрые методы, ибо лишняя миллисекунда порой превращается в лишнюю секунду.
0
В случае с JS лучше выбрать способ покороче, т.к. неизвестно, какой из способов является на самом деле быстрее, а в клиентском коде важен размер (чем меньше — тем лучше)
0
Это если ты не пишешь рендер, или какие-то другие могучие алгоритмы для обработки огромного кол-ва данных. Для простых приложений проблема преждевременной оптимизации не так критична.
Плюс там так и написали, что хорошо использовать так, но, а если будете вот так, то вообще крутые ребята.
Плюс там так и написали, что хорошо использовать так, но, а если будете вот так, то вообще крутые ребята.
0
Сейчас проверил в хроме, у меня typeof на 14% быстрее, чем in. При этом простое сравнение свойства с undefined работает почти на 40% медленнее чем in. Так что никаких заблуждений здесь нет, ребята показали максимально эффективный код.
0
(function (undefined) {
var count = 10000000, i;
console.time( 'typeof' );
for (i = count; i--;) (typeof undefined == 'undefined');
console.timeEnd( 'typeof' ); // 71
console.time( 'null' );
for (i = count; i--;) (undefined == null);
console.timeEnd( 'null' ); // 54
})();
Так что заблуждение есть. Ребята показали максимально длинный и, при этом, неэфективный код.
Но заметьте, разница в 17 мс на 10 миллионах вызовов!
И стоит убрать объявление undefined из заголовка функции (чтобы получать глобальную, а не локальную переменную), как время вырастет в десятки раз:
(function () {
var count = 10000000, i;
console.time( 'typeof' );
for (i = count; i--;) (typeof undefined == 'undefined');
console.timeEnd( 'typeof' ); // 2334
console.time( 'null' );
for (i = count; i--;) (undefined == null);
console.timeEnd( 'null' ); // 2307
})();
Так что просто получение значения глобальной переменной намного дольше, чем эти операции.
Потому ещё раз говорю — не занимайтесь глупостями.
0
Вот странно, мне кажется, что «even better» на главной — это не самое лучшее решение. Зачем узнавать тип, если undefined… всегда undefined…
Всегда писал так, уверен, что это 100% правильно. Может меня кто-то поправить?
if(document.attachEvent !== undefined)
document.attachEvent('onclick', someFn)
Всегда писал так, уверен, что это 100% правильно. Может меня кто-то поправить?
-1
Теоритически переменная undefined может существовать. Раз это возможно (пусть даже все понимают что строчку «var undefined = function(){}» мог написать только отъявленный психопат), то ваш подход не 100% правильный.
0
Мой модход 100% железный, всегда и всюду предохраняйся…
(function(undefined){
console.log(windov === undefined);
})();
0
Так антипаттерн как раз в том, что люди так не делают. Код приведенный вами в первом комменте без уточнения — антипаттерн.
0
Т.е. такой код… антипаттерн?
А вообще такой код используется в jQuery именно для того, чтобы нельзя было переопределить undefined и сломать код.
+ такой код вообще не меняет стандартное поведение, это лишь страховка.
Application.closure.apply(function(a, u, j, undefined){
//Эти сокращения хорошо задокументированны
//a - application
//u - underscore
//j - jQuery
});
А вообще такой код используется в jQuery именно для того, чтобы нельзя было переопределить undefined и сломать код.
(function(undefined){
})();
+ такой код вообще не меняет стандартное поведение, это лишь страховка.
-1
Первая строка кода… без комментариев и уточнения, это обычный хак JS.
code.jquery.com/jquery-1.7.2.js
code.jquery.com/jquery-1.7.2.js
0
Вы немного путаете (привожу код из jquery):
В вашем же примере:
(function( window, undefined ) { // смотрим описание функции, второй параметр называется undefined
})( window ); // смотрим вызов этой функции, передан только один аргумент, значит тип второго будет действительно undefined
В вашем же примере:
Application.closure.apply(function(a, u, j, undefined){ // здесь именно вызов функции, без контекста выглядит что undefined - это обычная переменная, и вы ее куда-то передаете. Выглядит как антипаттерн
//Эти сокращения хорошо задокументированны
//a - application
//u - underscore
//j - jQuery
});
0
JSLINT (http://jslint.com/) и многие IDE не любят такого, так как причесляют undefined к reserved words.
+2
Раз мы ударяемся в дебри того, что кто-то мог переопределить undefined, то тут мы должны дойти до того, что этот же псих мог бы переопределить attachEvent. Что, кстати, мне кажется более имеющим смысл.
0
глобального «undefined» нет в старых IE
0
5.5 и меньше? Ну и что?
0
это переменная не освящена стандартом, в отличии от typeof. хотя может и ошибаюсь.
0
Открыл первый pdf из гугла «JavaScript Language Specification»…
И целая глава из одного предложения.
The typeof operator returns a string indicating the type of its operand. The
string returned is one of
• “undefined”
• “object”
• “function”
• “number”
• “boolean”
• “string”
И целая глава из одного предложения.
The Undefined Type
Any variable that has not been assigned a value is automatically of type
undefined.
0
Ключевое слово: the string returned
то есть
то есть
typeof a == 'undefined'
— это согласно стандарту, а просто undefined
— на совести разработчиков браузеров0
Эм, я согласен, что мой англ не идеален. Но я кажется верно прочитал эти строки.
> string indicating the type
> The Undefined Type
> a value is automatically of type undefined.
А ваш пример только намекает, что в JS нет констант.
> the string returned
> string indicating the type
> The Undefined Type
> a value is automatically of type undefined.
А ваш пример только намекает, что в JS нет констант.
> the string returned
0
Не, есть в стандарте.
Конкретно раздел «15.1 The Global Object».
Там описаны еще NaN, Infinity, eval, к примеру.
Конкретно раздел «15.1 The Global Object».
Там описаны еще NaN, Infinity, eval, к примеру.
0
Листаю паттерны JQuery — в целом всё понятно, многое очевидно, но тут внезапно:
в первоисточнике к одному паттерну (который, кстати, никак не прокомментирован) сказано:
Объясните, в чем магия второго способа? Мне сложно представить, в чем кроется прирост производительности.
в первоисточнике к одному паттерну (который, кстати, никак не прокомментирован) сказано:
// regular
$(elem).data(key, value);
// OMG like 10x faster
$.data(elem, key, value);
Объясните, в чем магия второго способа? Мне сложно представить, в чем кроется прирост производительности.
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Коллекция паттернов и антипаттернов JavaScript