Comments 121
«Используйте более короткие сособы записи undefined».
Поправьте, очепятку.
Поправьте, очепятку.
-8
azproduction писал прикольную статью на эту тему.
+2
Многие трюки вполне нормально будут смотреться и в повседневной разработке.
+3
если использовать эти методы в крупных блоках кода, вы не только сэкономите байтики, но и гарантированно обеспечите себя и других разработчиков мигренью при дальнейшей работе с кодом :)
хотя в общем, очень даже интересная статья, познавательная.
хотя в общем, очень даже интересная статья, познавательная.
+15
Используйте UglifyJS для первичного сжатия кода — он сделает половину работы за вас.
+2
Uglify применяет лишь самые примитивные и теоретически безопасные методы сжатия. Здесь в основном перечислены post/pre-uglifier советы, базирующиеся на изначальной компоновке и построении кода. Аглифай не обладает интеллектом, чтобы применять подобные штуки.
И про более короткий undefined uglify тоже не знает :)
И про более короткий undefined uglify тоже не знает :)
+1
тут идет вопрос чисто о спортивном интересе — сделать код минимальным
посему автоматические штуки не пройдут
посему автоматические штуки не пройдут
+1
Еще давно в моей голове маразм крепчал очень сильно и я писал:
foo|=evt.keyCode==34
Вместо
if(evt.keyCode==34)foo=true;
foo|=evt.keyCode==34
Вместо
if(evt.keyCode==34)foo=true;
+4
Ещё очень много можно интересного сделать, если складывать с undefined и т.п.
+3
Вот ещё нашёл — поиск в строке
var a = 'some string';
if (!~a.search('b')) ...
+8
О, ради этого коммента закинул даже сам топик в мемориз!
+2
IndexOf быстрее чем search, как я понимаю это из-за того что в search'е можно использовать регулярные выражения.
Если экономите на спичках или искать нужно в большой строке indexOf использовать правильней.
Если экономите на спичках или искать нужно в большой строке indexOf использовать правильней.
0
Было бы занятно пройтись по измененному коду JSLint'ом…
+2
Быстрый запрос к серверу (только push и без возможности ответа):
var i=new Image;
i.src='http://url.here?need=data';
+5
(new Image).src='http://url.here?need=data';
+6
Маньяк :)
+1
Или так:
new Image().src='http://url.here?need=data';
+3
В пути к ресурсам не обязательно указывать протокол (будет установлен текущий). Не уверен, что работает во всех браузерах. Для URL можно использовать короткие ссылки — j.mp (короче j.mp только свой домен первого уровня)
// "//j.mp/hW9b6U" === "http://yandex.ru/favicon.ico"
new Image().src='//j.mp/hW9b6U';
+4
В ответ можно получить ширину и высоту картинки. Иногда этого достаточно.
+9
Почему без возможности. Можно вернуть error (и обработать onerror или onload).
+1
Я имел ввиду — осмысленный ответ (строку, JSON и т.д.). Но так — да: проверить наличие атрибута width либо вешаться на onload/onerror. Это только проверка доставки данных, но полноценного транспорта не выйдет. Но, плюсом является абсолютная кроссдоменность :)
+1
Осмысленное что-то можно в cookie передать.
+1
Даёшь аякс транспорт в 1000 байт!!! :)
+1
Хватит и 118
Кросс-браузерный немного длиннее
Usage:
function xhr(m,u,c,x){with(new XMLHttpRequest)onreadystatechange=function(x){readyState^4||c(x.target)},open(m,u),send©}
Кросс-браузерный немного длиннее
function xhr(m,u,c,x){with(new(this.XMLHttpRequest||ActiveXObject)("Microsoft.XMLHTTP"))onreadystatechange=function(x){readyState^4||c(x)},open(m,u),send©}
Usage:
xhr('get', '//ya.ru/favicon.ico', function(xhr){console.dir(xhr)});
+6
Как развлечение одобряю, но выпускающих такое в продакшен надо драть нещадно.
+1
Неделя JavaScript прекрасна:)
+9
Используйте еще более короткие способы записи undefined
function a(a){if(a==[]._){...};c=[]._}
function a(a,b){if(a==b){...};c=b}
+2
А чем плохо?
if (a == null)
+1
a==b короче.
+1
согласен, но не вижу смысла в []._
+1
Я тоже не вижу. Но вижу смысл в a === []._
+1
А я вижу — путать людей не посвященных в JavaScript :) Вот вам quiz:
var N = 3;
while (1..N) {
alert(0); // <<< Сколько раз отработает alert?
}
// или вот так
var N = 3;
while (a in [1..N]) {
alert(a); // <<< Сколько раз отработает alert и что выведет?
}
+1
Я очень долго пытался понять что же здесь написано :) Наконец догадался. Но спасибо, мозг мне коротнуло :) Правда надо ещё «а» описать, иначе операция in не сработает.
+1
в JavaScript есть диапазоны как в Ruby!!?
0
Нет. Это обман зрения :) Давайте разберем:
1. мы у
2. в итоге мы имеем массив
3. дальше мы пытаемся узнать, а есть ли что-то с ключем
Сколько раз отработает alert?: Ответ в обоих случаях — 0
var N = 3, a; while (a in [1..N]) ...
1. мы у
1.0 (1.)
пытаемся получить свойство N через точечную нотацию — его нет, поэтому 1..N
возвратит undefined
. Переменная N объявлена для отвлечения и никакой нагрузки не несет.2. в итоге мы имеем массив
[undefined] - (0: undefined)
, 3. дальше мы пытаемся узнать, а есть ли что-то с ключем
undefined
(a===undefined
) в нашем массиве — a in [undefined]
получаем false.Сколько раз отработает alert?: Ответ в обоих случаях — 0
0
вместо длинного
undefined
можно использовать более симпатичное 0..O
0
как бы null и undefined — две огромных разницы
+1
Не такие уж и большие
null == undefined; // true
undefined == null; // true
null == 0; // false
undefined == 0; // false
+1
А в ракурсе typeof? :)
Ну окромя шуток семантика (или точнее когда значения являются/становятся нуллами, а когда андефами) действительно отличается.
Ну окромя шуток семантика (или точнее когда значения являются/становятся нуллами, а когда андефами) действительно отличается.
+1
Я отвечал на комментарий
+1
* Я отвечал на комментарий
В таком виде разницы действительно нету.
Между прочим, как раз, семантика очень похожа и многие фреймворки используют именно == null в силу лаконичности и очевидности.
jQuery:
MooTools:
if(a==[]._)
В таком виде разницы действительно нету.
Между прочим, как раз, семантика очень похожа и многие фреймворки используют именно == null в силу лаконичности и очевидности.
jQuery:
get: function( num ) {
return num == null ?
// Return a 'clean' array
this.toArray() :
// Return just the object
( num < 0 ? this[ this.length + num ] : this[ num ] );
},
MooTools:
+1
Да что ж такое:
Function.prototype.overloadSetter = function(usePlural){
var self = this;
return function(a, b){
if (a == null) return this;
// ...
};
};
+1
И, вообще не понимаю, зачем столь близкие по смыслу значения. Оставили бы один null — его бы хватило с головой.
+1
Иногда возникают ситуации, когда нужно чётко отличать задание «пустого» значения и не задание вообще никакого и в некоторых ЯП undefined значения не хватает.
+1
А как отличить задание undefined значения и вообще никакого? ;)
+1
С массивами, например, прокатывает такая штука
0 in [undefined] // true
0 in [] // false
+1
Аналогично прокатывает с null ;)
Имхо, undefined — это тот же null, но просто ещё более null. =)))
0 in [null] // 0
Имхо, undefined — это тот же null, но просто ещё более null. =)))
+1
Чтобы не путать читателей уточню:
null — примитивное значение, представляющее нулевую, пустую, не существующую ссылку
undefined — примитивное значение, которое получает каждая перемененная по умолчанию (когда переменная не имеет значение)
void — оператор (т.е. скобки не нужны), выполняющий выражение и всегда возвращающий undefined
В JavaScript, кстати, каждая функция по умолчанию возвращает undefined
null — примитивное значение, представляющее нулевую, пустую, не существующую ссылку
undefined — примитивное значение, которое получает каждая перемененная по умолчанию (когда переменная не имеет значение)
void — оператор (т.е. скобки не нужны), выполняющий выражение и всегда возвращающий undefined
В JavaScript, кстати, каждая функция по умолчанию возвращает undefined
(function(){}()) === void 0 // true
+2
Запретить присваивать undefined? :)
+1
Если вернуться к «истокам», когда переменные имели строгую типизацию, объявление переменной влекло за собой выделение памяти или запись в таблицу идентификаторов. undefined переменные были те, объявления которых вообще не было. После объявления переменной, она равнялась null, типа вообще ничего никогда не записывали в память, но информация о переменной уже записана в таблицу переменных.
Варианты реализации могли быть разными, но в общем примерно так. Аналогичное поведение сделали в JS, но разницы особо в них нет из-за условий сравнения и приведения типов.
Варианты реализации могли быть разными, но в общем примерно так. Аналогичное поведение сделали в JS, но разницы особо в них нет из-за условий сравнения и приведения типов.
0
Сравнение через
Тоже получается не такая уж и большая разница :)
==
не в счет, поскольку, например"" == [[[[[,]]]]] // true
Тоже получается не такая уж и большая разница :)
+2
На самом деле это переход на личности. То, что нестрогое сравнение где-то имеет не совсем логичный результат — ничего не значит. Оно семантически верно сравнивает с null. Например, мы хотим удостовериться, что в конструктор передан аргумент:
Мне кажется, что последний пример намного логичнее и лаконичнее, тем более, что в данном примере нельзя воспользоваться arguments.length:
function Point (x, y) {
if (typeof x == 'undefined' || typeof y == 'undefined') throw new TypeError();
this.x = x;
this.y = y;
};
// или даже
function Point (x, y) {
if (x === undefined || y === undefined) throw new TypeError();
this.x = x;
this.y = y;
};
// vs
function Point (x, y) {
if (x == null || y == null) throw new TypeError();
this.x = x;
this.y = y;
};
Мне кажется, что последний пример намного логичнее и лаконичнее, тем более, что в данном примере нельзя воспользоваться arguments.length:
function PointFactory (x, y) {
return new Point(x, y);
};
+3
Что-то я не уловил тут перехода на личности. А ты, по-моему, слишком напрягся от очередного ничего не значащего шуточного коммента. :)
Тем не менее бывают случаи, когда надо отличить
Да и вообще, мне не сильно понятен предмет спора — есть две сущности, которые иногда ведут себя схоже и взаимозаменяемы, а иногда нет. В некоторых случаях можно использовать любую из двух, в других нет. Вот, собственно, и все.
Касательно твоего примера полностью соласен — последний вариант выглядит наиболее лаконично.
Тем не менее бывают случаи, когда надо отличить
null
от undefined
. И тогда []._
вполне себе будет уместен.Да и вообще, мне не сильно понятен предмет спора — есть две сущности, которые иногда ведут себя схоже и взаимозаменяемы, а иногда нет. В некоторых случаях можно использовать любую из двух, в других нет. Вот, собственно, и все.
Касательно твоего примера полностью соласен — последний вариант выглядит наиболее лаконично.
+1
Первые два сравнения — исключительные ситуации
0
Между прочим, ко мне только что пришло озарение, как создавать и использовать короткие функции (только для современных браузеров).
with({ get a () { return Math.random() } }) {
alert(a)
}
+1
Тоже не во всех браузерах, но ещё короче:
with({get a()Math.random()}) {
alert(a)
}
+1
Расскажите, что это?)
+1
Javascript Getter в совокупности с with =)
+1
А azproduction комментом ниже использовал Expression closures из javascript 1.8, который поддерживается только Firefox3+
Подробнее: habrahabr.ru/blogs/javascript/113344/
Подробнее: habrahabr.ru/blogs/javascript/113344/
+1
Вообще парни как-то маловато способов описали.
+1
Глюкнутый но рабочий польский калькулятор, всего две команды + и -. 120 байт
(function(e,s,i,o){
while(o=e[i++])
s.push(
+o?+o:
s.pop()*(o=='+'?1:-1)+s.pop()
);
alert(s.pop())}
)(prompt().split(' '),[],0);
(function(a,b,c,d){while(d=a[c++])b.push(+d?+d:b.pop()*(d=="+"?1:-1)+b.pop());alert(b.pop())})
(prompt().split(" "),[],0)
+1
Самый короткий и кросс-браузерный код для определения браузера в 83 байта!
Формат переменной b:
Можно немного короче, но тогда не будет булеанов. Код использует особенность имени прототипа воркера, которую я описал тут. Надо будет выложить на 140byt.es
w=this.Worker,l=w&&(w.prototype+"").length,b={f:l==36,o:l==33,s:l==24,c:l==15,i:!w}
Формат переменной b:
{
f: {true|false}, // Firefox
o: {true|false}, // Opera
s: {true|false}, // Safari
c: {true|false}, // Chrome
i: {true|false} // IE любой
}
Можно немного короче, но тогда не будет булеанов. Код использует особенность имени прототипа воркера, которую я описал тут. Надо будет выложить на 140byt.es
+9
Этот же код в удобочитаемом виде gist.github.com/989440
+1
Простите, промахнулся, см. коммент ниже
+1
c false
f false
i true
o false
s false
Это результаты для ФФ 3.6.17 ;)
+1
А все потому, что
console.log(this.Worker); // undefined
+1
Очень странно. Воркеры появились в Firefox 3.5, да и я проверял их наличие goo.gl/tD1jr Вы случайно не используете IE Tab?
+1
Читаю топик и ощущение «дежа вю». Потом понял — это же «Совершенный код» в формате «вредных советов» :D
+1
Если a = 2
Вывод «not one» будет только в первом случае
Наверное имелось ввиду что-то подобное:
Тогда в обоих случаях будет вывод «not one»
a==1||console.log("not one") // до
~-a||console.log("not one") // после
Вывод «not one» будет только в первом случае
Наверное имелось ввиду что-то подобное:
if(a!=1) console.log("not one") // до
if(~-a) console.log("not one") // после
Тогда в обоих случаях будет вывод «not one»
+2
1 in arguments||(cb=alert) // до
arguments[1]||(cb=alert) // после
+1
a=[];for(b in window)a.push(window[b]) // до
a=[];i=0;for(a[i++]in window); // после
Не эквивалентные записи, в первой получим значения, а во второй ключи.
Если исправить
a=[];for(b in window)a.push(b) // до
то строки будут одинаковой длины :) но второй вариант оригинален…
Так же стоит заметить, что многие из описанных «оптимизаций» делает Closure compiler
0
еще вариант итерации по массиву:
i=a.length; while(i--){b=a[i];...};
0
полнейший идиотизм, когда же этот ** твитер сдохнет со своим числом 140
бре-
э-
эд
бре-
э-
эд
-1
из коротких способов записи undefined самым быстрым оказался void 0, потом почти так же 0[0]
algos = [["void 0", function(){void 0;}] ,["\"\"._", function(){""._;}]
,["1.._", function(){1.._;}] ,["0[0]", function(){0[0];}]];
var tms=[];
for(i in algos)
{
tms[i] = +new Date();
for(var k=0;k<10000000;k++)
{
algos[i][1]();
}
tms[i] = (+new Date()) - tms[i];
}
0
Sign up to leave a comment.
Техники сжатия кода