Нестандартное поведение стандартного оператора ||
Иногда при кросс браузерном программировании бывает нужно выбрать из двух или более переменных которые зависят от типа браузера. Например типичный пример - отслеживание событий мыши - в IE параметры события берутся из глобального объекта event а в Firefox и многих других браузерах event передается как формальный параметр в обработчик события. Поэтому необходимо выбирать тот или иной способ получения этого объекта в зависимости от того какой браузер.
Самое первое, что приходит на ум это использовать тернарный оператор "<condition>?<if true>:<if false>":
a.onclick = function(e){
var ev = e?e:event;
//далее работаем с ev
}
Сегодня мне предложили еще более короткую запись:
a.onclick = function(e){
var ev = e||event;
//далее как обычно
}
Все отлично, все логично, но почему это работает? В MSDN четко сказано что || оператор логический и возвращает он true или false в зависимости от входных параметров. Если параметры на входе не логические то приводятся к логическим, т.е. не должно так работать а работает.
Скорее всего операция || возвращает первый не ложный аргумент, причем возвращает по ссылке в чем нетрудно убедиться:
var v1; //undefined
var v2 = {};
var result = v1 || v2;
alert(result===v2); //true
Интересно, такое поведение где нибудь документировано или это хак?
UPD: Оказыватся у Мозиллы все подробно на этот счет расписано:
https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Operators/Logical_Operators
Базовый класс для наследования в JavaScript
Под впечатлением класса разработанного Дином Эдвардсом создал свой собственный класс, который позволяет значительно упростить структуру программ на JavaScript где необходимо неследование.
Основные особенности следующие:
- маленький и простой - неминифицированный размер: 622 байта.
- конструктор описывается явно как функция с именем 'constructor'
- наследование статических и обычных членов класса
- при определениии объекта не используется MyClass.prototype;
- не используются глобальные функции для создания цепочек прототипов;
- не изменяется Object.prototype.
Вот пример использования:
var Animal = BaseClass.extend({
constructor:function(){
alert("Anumal is created!");
},
say:function(){
alert("hm...");
}
});
ver Cow = Animal.extend({
constructor:function(){
alert("Cow is created!");
},
say:function(){
alert("mooo");
}
});
var cow1 = new Cow();
cow1.say();
Фактически, от версии Дина отличается только отсутствием статических методов на этапе наследования - их можно и явно прикрутить, что улучшит читаемость кода, также отсутствует метод super, на мой взгляд у Дина эта штука будет понижать производительность, перегруженных функций независимо используется super или нет, поэтому я решил от неё отказаться, к тому же её можно эмулировать просто отдельной функцией.
Upd. Позже я пересмотрел мысль насчет super и включил её в реализацию метода. В ztools.org можно найти последнюю версию функции.
Опрос вебсервера по протоколу HTTP
Каждый раз когда хочется посмотреть что реально возвращает сервер приходится открывать telnet, ручками набирать комманды, что, согласитесь, довольно трудоемко и требует предельной аккуратности, особенно если запросы довольно большие, если же нужно отлаживать POST запросы то задача становиться вообще трудноразрешимой.
Для того чтобы упростить себе жизнь создал такой вот небольшой инструмент для опроса вебсервера. Разумеется с исходником.
strpos vs. ereg vs. preg_match
Тут возник вопрос как между собой соотносится быстродействие POSIX регулярных выражений, Perl-совместимых регулярных выражений и кодирования "в лоб" с использованием обчных си-подобных str* функций. Можно долго на эту тему рассуждать, поэтому привожу тест который расставляет все по местам. Исходник здесь
