суббота, 17 сентября 2011 г.

JavaScript: Присвоить метод строке или числу

Как говорится: «век живи — век учись». Я тут (не без помощи форума nodejs.ru) узнал интересный факт. Много где говорится об эквивалентности создания новой строки таким способом:
var str = 'Hello world';
С таким:
var str = new String('Hello world');
Но на самом деле, — это даёт разные результаты. Если под рукой есть Firebug, — проверьте и убедитесь сами. А тут я хочу подметить по теме о присваивании метода к строке или числу, дальше думаю сами всё поймёте:
var str = 'Hello world';
str.mthd = 123;
str; //Hello world
str.mthd; //undefined

var str2 = new String('Hello world');
str2.mthd = 123;
str2; //Hello world или объект String в отладчике {mthd: 123, 0: 'Hello world'}
str2.mthd; //123
Аналогично с new Number(), экспериментируйте!
 
И на закуску:
(new String('Hello world') === 'Hello world') //false
(new String('Hello world') == 'Hello world') //true
Спасибо некоему AbS_!

Внимание! Подводные камни!

Впоследствии практическим путём я наткнулся на подводные камни! В частности, когда я захотел вернуть в Node.JS ответ HTTP-сервера на запрос объектом строки:
require('http').createServer(function (req, res) {
    var str = new String('ok');
    res.end(str);
}).listen(8000);
При обращении к http://127.0.0.1:8000 процесс ноды обваливался с ошибкой:
TypeError: first argument must be a string or Buffer
Чтобы обойти проблему, — нужно дописывать к выводу строки вызов метода .toString(), — дабы преобразовать объект в обыкновенную строку, из строки-объекта:
res.end(str.toString());
Штука тут в следующем:
typeof new String('check') //returns 'object'
typeof 'check' //returns 'string'
Так что, коли решились использовать строку как объект, будьте бдительны и осторожны!

пятница, 19 августа 2011 г.

Node.JS: Рекурсивный extend (node-deep-extend)

При разработке на Node.JS пользуюсь фреймворком Underscore.js, но к своему сожалению я обнаружил, что у него нет рекурсивного extend-а, который мне нужен как минимум при организации новых модулей, где есть файл конфигурации. Просто выпилить например из jQuery не получилось, поскольку там есть отсылки к другим методам из jQ. В итоге решил, что проще уже будет набросать новый велосипед.

И вот сделал себе плюшку в виде модуля, которая доступна всем на GitHub-е:
http://github.com/unclechu/node-deep-extend

UPD 11.04.2012: Теперь и в NPM: npm install deep-extend

четверг, 11 августа 2011 г.

1С-Битрикс: Иерархичное меню и result_modifier

Приветствую! Наверное уже есть множество способов решения данной задачи, но я решил сделать новый велосипед. Зачем? Не знаю. Захотел сделать простое и кроткое решение. Пожалуй не только мне досаждает то, что у Битрикса стандартный шаблон модуля меню почему-то выдаёт массив элементов одним уровнем и вложенность определяется только по ключу DEPTH_LEVEL. Приходится выкручиваться всякими финтами с подстановкой </li></ul> в начале новой итерации цикла, но это эстетически никак не доставляет, полагаю, что никому.

Я написал простой result_modifier.php, который подкладываю в директорию шаблона:
<?
if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();

$menuList = array();
$lev = 0;
$lastInd = 0;
$parents = array();
foreach ($arResult as $arItem) {
    $lev = $arItem['DEPTH_LEVEL'];
    
    if ($arItem['IS_PARENT']) {
        $arItem['CHILDREN'] = array();
    }
    
    if ($lev == 1) {
        $menuList[] = $arItem;
        $lastInd = count($menuList)-1;
        $parents[$lev] = &$menuList[$lastInd];
    } else {
        $parents[$lev-1]['CHILDREN'][] = $arItem;
        $lastInd = count($parents[$lev-1]['CHILDREN'])-1;
        $parents[$lev] = &$parents[$lev-1]['CHILDREN'][$lastInd];
    }
}
$arResult = $menuList;
В итоге мы имеем ключ CHILDREN у пункта меню, если у него имеются дочерние пункты меню, и соответственно дочерние у дочерних (we need to go deeper). Обычное и логичное разветвлённое иерархичное меню.

Вот код в файле: http://lotsmanov-va.narod.ru/files/bitrix_blog/menu_levels/result_modifier.txt

UPD 11.08.2011: Исправил имя ключа children на CHILDREN, совсем забыл про единство стиля.

пятница, 3 июня 2011 г.

Node.JS: Native JavaScript Templates (nJSt). Шаблонизатор, построенный на нативном JavaScript

Приветствую тебя, читатель. Гоняясь за идеей сделать шаблонизатор, основанный на нативном JavaScript — я кое к чему пришёл. В Node.JS для реализации этой задачи нашлось всё, что я мог пожелать, и выполнить задачу получилось настолько же нативными средствами. Например, главным инструментом послужил модуль VM для выполнения изолированного от внешней среды JavaScript-кода. Шаблонные вставки — это чистый JS, но туда не попадают всяческие опасные инструменты вроде скальпеля, require, global и др.

Перед тем как приступить к подробному разбору полётов, сразу взглянем на пример использования, который скорей нагляднее отразит суть, чем что-либо ещё. Код создания сервера приводить не буду, просто опишу сам шаблон и парсинг под определённым контекстом.

HTML-шабон:
<html>
<head>
    <title>#{PageTitle}</title>
</head>

<body>
    <h1>#{PageTitle}</h1>

    <ul>
    <# for (var i=0; i<List.length; i++) { #>
        <li>
            <#
                if (typeof List[i] !== 'object') {
                    show(List[i]);
                } else {
                    show(List[i].name +' - '+ List[i].note);
                }
            #>
        </li>
    <# } #>
    </ul>
</body>
</html>

Контекст:
var context = {
    PageTitle: 'jJSt test',
    List: ['First', {name:'Second', note:'2th'}, 'Third'],
};
var result = njst.parse(html, context, {debug:1});

пятница, 20 мая 2011 г.

Node.JS: Учимся создавать маленький парсер шаблонов

Приветствую тебя, читатель. Ещё давеча я даже не знал о существовании Node.js, но зато успел увесисто поработать с JavaScript, после которого так не хочется писать на чём-либо другом. Многие, кто вник в JS и его дзен, что всё есьм — объект, в замыкания, анонимные функции, предпочитают работать только с ним. Однажды с товарищем обменивались мыслями о PHP, покритиковали скудные и неудобные возможности ООП, и я тут выдал: «вот бы вместо PHP на серверной стороне писать на JS», — на что получил мгновенный ответ: «nodejs тебе в руки». Не долго думая я начал рыть по wiki и другим ресурсам, далее в кротчайший срок я поднял Ubuntu Server на Virtual Box и поставил туда сам Node.js.

Сразу предупреждаю, что если вы не работали с JavaScript или просто скудно с ним знакомы, начните именно с него, иначе Node.js может показаться вам тёмным лесом. Хочу познакомить вас с языком сразу на практике, и так же показать идею по опять же практическому применению. Я приведу пример реализации маленького парсера шаблонов, всё это уложится в 2-а небольших файла, нарочито без излишеств, чтобы наглядно и прозрачно посмотреть «как это работает».

четверг, 5 мая 2011 г.

PHP: Класс ucResizeImg v2.0, универсальный алгоритм ресайза изображений

Первоначально приветствую вас и надеюсь вы не потратите время зря. Следующий модуль я создавал первоначально для себя, стараясь покрыть все возможные тривиальные (может некоторые и не совсем тривиальные) задачи, касательно резайзинга изображений на серверной стороне. Но также хочу поделиться со всеми своим трудом, поскольку прошлая версия этого модуля, намного менее совершенная, получила резонанс, и пришлась очень кстати многим. Это был файл, содержащий 2-е функции: http://dev.1c-bitrix.ru/community/webdev/user/25535/blog/1446/

По советам потребителей прошлой версии, я объединил эти 2-е функции в одну, если так можно сказать. Я создал класс, существенно расширив функционал и универсальность, также используя более дружелюбную параметризацию. 1С-Битрикс режим теперь включён внутрь класса, нужно только активировать его, в то время как в прошлой версии — это были два отдельных скрипта. Обо всех изменениях думаю рассказывать сейчас не стоит, ибо скорее всего вы видите этот модуль впервые, лучше я расскажу о каждой возможности отдельно. Да и по-моему эту версию и прошлую уже можно считать двумя разными не связанными между собой скриптами.

Возможности модуля:
  • Получение отрезайзеного изображения;
  • Поддержка форматов: JPEG, PNG, GIF (выходящий файл всегда JPEG);
  • Кеширование выходящих файлов;
  • Гибкая и универсальная параметризация;
  • Совместимость с 1С-Битрикс;
  • Возможность выдавать строгие размеры изображения;
  • Имеется режим отладки.