Ссылки о веб-разработке за май 2011

JavaScript-гольф

Shared by arty
куча забавных штук, которые никогда нельзя использовать : )
Джед Шмидт, Томас Фухс и Дастин Диаз — достаточно известные в JavaScript-коммьюнити ребята в последнее время нашли себе новую развлекуху — писать полезные штуки размером не больше одного твита, то есть 140 байт. Даже домен зарегали — 140byt.es, куда приглашаются все желающие попробовать свои силы в написании супер-компактных функций.

Естественно, в ход идут все самые изощренные способы и техники уменьшения размера исходника. У них есть вики-страничка с советами, которую я и решил перевести.

Сразу оговорюсь, что читаемость обработанного таким образом кода стремится к нулю, так что использовать эти трюки стоит только в случаях, когда размер действительно превыше всего. Например, при участии в конкурсе JS1k.

Итак.

Arguments


Используйте однобуквенные позиционные аргументы в алфавитном порядке


Поскольку аргументы функции должны быть как можно более короткими, и скорее всего будут использованы по несколько раз во время выполнения, проще рассматривать их с точки зрения позиции и именовать в алфавитном порядке, вместо того, чтобы пытаться давать им сколько-либо осмысленные имена.
function(t,d,v,i,f){...} // до
function(a,b,c,d,e){...} // после


Проверяйте наличие аргументов вместо длины


Можно использовать in для проверки наличия аргумента.
arguments.length>1||(cb=alert) // до
1 in arguments||(cb=alert)     // после


Переменные


Используйте «лишние» аргументы вместо var


Можно сэкономить несколько байт указав лишний аргумент в функции, вместо объявления переменной с помощью var:
function(a){var b=1;...} // до
function(a,b){b=1;...}   // после


Используйте переменные по несколько раз


setTimeout(function(){for(var i=10;i--;)... }, a) // до
setTimeout(function(){for(a=10;a--;)... }, a)     // после


Используйте присваивание там, где это возможно


Поскольку оператор присваивания возвращает присваиваемое значение, можно использовать присваивание и проверку одновременно:
a=this.localStorage;if(a){...} // до
if(a=this.localStorage){...}   // после


Используйте массив чтобы поменять местами переменные


Массив можно использовать как временное хранилище, чтобы не объявлять лишнюю переменную.
var a=1,b=2,c;c=a;a=b;b=c // до
var a=1,b=2;a=[b,b=a][0]  // после


Используйте приведение типов при сложении


Приведение типов в JS работает весьма странно и является одним из самых распространенных источником багов. Тем не менее, его можно использовать разными интересными способами для уменьшения размеров кода.
Наример, в реализации pubsub Джед Шмидт декрементировал переменную с отрицательным числом, а затем прибавлял ее к строке, получая что-то вида "somestring-123".
После этого в другом месте использовал .split('-') для получения исходной строки.

Циклы


Опускайте тело цикла


Зачастую можно реализовать всю логику внутри условий и сэкономить на теле цикла.
Хороший пример этого подхода можно посмотреть в функции timeAgo.

Используйте for вместо while


for и while обычно занимают одинаково количество байт, но for позволяет получить больший контроль и больше возможностей для присваивания.
while(i--){...} // до
for(;i--;){...} // после

i=10;while(i--){...} // до
for(i=10;i--;){...}  // после


Используйте быструю итерацию по «правдивым» массивам


Если у вас есть массив, все члены которого заведомо приводятся к true, можно использовать более короткую запись цикла:
for(a=[1,2,3,4,5],l=a.length,i=0;i<l;i++){b=a[i];...} // до
for(a=[1,2,3,4,5],i=0;b=a[i++];){...}                 // после


Используйте for..in с присваиванием для получения ключей объектов


a=[];for(b in window)a.push(window[b]) // до
a=[];i=0;for(a[i++]in window);         // после


Операторы


Выучите приоритет операторов


Эти знания могут помочь неплохо сэкономить на скобках.
Начать можно с изучения этой статьи на сайте Mozilla.

Используйте ~ c indexOf


hasAnF="This sentence has an f.".indexOf("f")>=0 // до
hasAnF=~"This sentence has an f.".indexOf("f")   // после


Используйте запятую для последовательного выполнения операторов вместо блока


with(document){open();write("hello");close()} // до
with(document)open(),write("hello"),close()   // после


Используйте более короткие способы записи undefined


Вместо undefined можно использовать []._ или void 0.
Есть варианты ""._, 1.._ и [][0], но они намного медленнее.

Удаляйте необязательные пробелы перед операторами


Иногда пробелы после операторов можно безболезненно удалить.
typeof [] // до
typeof[]  // после


Числа


Используйте ~~ или 0| вместо Math.floor


rand10=Math.floor(Math.random()*10) // до
rand10=0|Math.random()*10           // после


Используйте экспоненциальный формат для больших круглых чисел


million=1000000 // до
million=1e6     // после


Используйте побитовые сдвиги для больших бинарных чисел


color=0x100000 // до
color=1<<20    // после


Используйте 1/0 вместо Infinity


Это короче. Кроме того, делить на нуль всегда весело.
[Infinity,-Infinity] // до
[1/0,-1/0]           // после


Используйте «ложность» нуля


Вместо сравнивания чисел иногда короче свести значение к нулю и проверить его истинность.
a==1||console.log("not one") // до
~-a||console.log("not one")  // после


Используйте ~ чтобы изменить любое значение на единицу


В сочетании с унарным минусом это дает возможность, например, инкрементировать любую, даже еще не определенную переменную.
// i = undefined
i=i||0;i++ // до
i=-~i      // после


Строки


Разбивайте строки с помощью нуля


Можно сэкономить два байта при разбиении строк методом split, если в качестве разделителя использовать нуль:
'alpha,bravo,charlie'.split(',') // до
'alpha0bravo0charlie'.split(0)   // после


Используйте браузерный метод link


Строки в браузерах имеют не очень известный метод link, который создает html-ссылку.
html="<a href='"+url+"'>"+text+"</a>" // до
html=text.link(url)                   // после


Используйте методы replace и exec для итерации по строкам


Эти методы позволяют передавать функцию в качестве второго аргумента. Этим можно воспользоваться для удобной итерации по строке.
Примеры использования: templates и UUID.

Используйте массивы для создания простых строк


for(a="",i=32;i--;)a+=0 // до
a=Array(33).join(0)     // после


Регулярные выражения


Используйте {n} для укорачивания рeгулярных выражений. Например /\d{3}/ вместо /\d\d\d/. И наоборот /\d\d/ вместо /\d{2}/.

Можно использовать eval вместо конструктора регулярки:
r=new RegExp("{"+p+"}","g") // до
r=eval("/{"+p+"}/g")        // после


Boolean


Используйте ! с цифрами для создания true и false.
[true,false] // до
[!0,!1]      // после


Функции


Используйте именованные функции для рекурсии вместо циклов


Зачастую это получается короче, поскольку позволяет протаскивать значения через стек, без лишних переменных.
В качестве примера функция walk.

Используйте именованные функции для хранения состояния


Если надо хранить состояние между вызовами функции, функцию можно использовать как объект и хранить данные в ее свойствах:
function(i){return function(){console.log("called "+(++i)+" times")}}(0) // до
(function a(){console.log("called "+(a.i=-~a.i)+" times")})              // после
0,function a(){console.log("called "+(a.i=-~a.i)+" times")}              // еще вариант


Опускайте скобки при вызове конструктора без аргументов


now = +new Date() // до
now = +new Date   // после


Опускайте ключевое слово new там, где это возможно


Некоторым конструкторам вовсе не обязательно ключевое слово new.
r=new Regexp(".",g) // до
r=Regexp(".",g)     // после

l=new Function("x","console.log(x)") // до
l=Function("x","console.log(x)")     // после


Оператор return


Когда надо вернуть что-то отличное от переменной, ставить пробел после return не обязательно.
return ['foo',42,'bar']; // до
return['foo',42,'bar'];  // после
return {x:42,y:417}; // до
return{x:42,y:417};  // после
return .01; // до
return.01;  // после


Пока все.

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

The Opera Payment Exchange - pay through your browser

In the future, it will be possible to do payments directly through Opera Mini. It will work as a "Consumer Wallet", and will provide an API that can be used by 3rd party billing services. There will also be reporting and analytics, and even fraud screening.

It seems that this can be tied to operator gateways, and will provide a secure way to do purchases online, directly through the browser.

← предыдущий месяц