Речь в сегодняшней статье пойдёт в основном о яваскриптах, потому что именно их я преподаю сейчас стажёру нашей компании. Поэтому статья носит в основном методологический характер.
Что такое объект?
Поскольку яваскрипт, в общем-тообъектно-ориентированный язык, мы повторяли определение что же такое объект в программировании и в яваскриптах в частности. Поискав для сравнения определения в интернете я ничего хорошего не нашла. Во всех источниках упоминается полнейшая чушь, что становится конечно понятно откуда берётся каша в головах студентов, соискателей, и стажёров. Потому что, вместо того чтобы делать знания простыми и понятными методологисты переписывают одни и те же книжки каждый раз только запутывая формулировки. Впрочем к концу статьи, я думаю вы запутаетесь сами =). Пока процитирую некоторые определения из википедии:
Объект — Сущность в адресном пространстве вычислительной системы, появляющаяся при создании экземпляра класса или копирования прототипа (например, после запуска результатов компиляции и связывания исходного кода на выполнение). Википедия
Заметьте, в довольно простое определения навязали адресное пространство, компиляцию, классы и прототипы. Это всё равно что спросить что такое птица, а в ответ получить что это сущность употребимая в пищу и вылупляющаяся из яиц!
Объект — некоторая сущность в виртуальном пространстве, обладающая определённым состоянием и поведением, имеет заданные значения свойств (атрибутов) и операций над ними (методов). Как правило, при рассмотрении объектов выделяется то, что объекты принадлежат одному или нескольким классам, которые в свою очередь определяют поведение (являются моделью) объекта. Время с момента создания объекта (конструкция) до его уничтожения (деструкция) называется временем жизни объекта
Я не читала таких определений, когда начала изучать яваскрипты, поэтому интуитивно они представляются совсем по другому. Это понятие класса должно строится на понятии объекта, а не понятие объекта строится на понятии класса.
Объект — это сущность, которой можно посылать сообщения, и которая может на них реагировать, используя свои данные. Данные объекта скрыты от остальной программы. Сокрытие данных называется инкапсуляцией.
Опять таки. В определении говорится об инкапсуляции. А что если данные объекта не скрыты? В прочем поскольку моя статья про яваскрипты, данное определение вообще никакой смысловой нагрузки не несёт.
Объект в программировании, это такая штука, которая не всегда может иметь визуальное представление, типа кнопки или поля. Скорее наоборот.
Представь себе массив — упорядоченный набор переменных. Каждая переменная в обычном массиве может содержать строку, число, (любую типизированную переменную) или другой массив. Поэтому моё определение звучит так:
Объект — это массив, который может содержать в качестве переменных, кроме всего прочего, функции или другие объекты.
Такое определение я призываю запомнить стажёров, потому что это именно то, с чем мы работаем в яваскриптах.
Справедливости ради, хочется так же отметить определение из англоязычной версии. Оно довольно хорошее.
Т. е. данные, и набор функций (методов) для работы с этими данными называются объектом.
Такой вариант так же допустим для запоминания. А теперь мне хочется рассказать почему яваскрипт это целиком объектно-ориентированный язык, и какие сложности в обучении ему возникают.
Объекты в Javascript
Теперь внимание, дальше вы можете запутаться!
В яваскриптах — почти всё является объектами, но не всё называется объектами. Число — или строковая переменная (или сущность) — не называются сами по себе объектами! Но по факту — являются ими.
Например у числа или строки могут быть встроенные функции. Т. е. функция.split например — аналог строковой функции explode в php и т. п.
var a = 'te.st';
var b = a.split('.'); // в b - будет массив из значений te и st
Чтобы понять сказанное выше утверждение, приведу такой аналог: «насекомые и птицы — не называются животными, хотя по факту являются ими». Т. е. вы видите на улице собаку или слона и говорите «О, какое животное». А когда видите птицу, говорите «какая птица», хотя из биологии это тоже царство животных. А собаки или слоны относятся к млекопитающим. Так и тут, когда вы видишь число или строку — нет нужды говорить «о, какой объект». Лучше сказать какая строка или какое число. А вот когда вы видите, например, документ html — document, или его тело — document.body — тут уж можно сказать «какой объект», просто потому что он уже и не число и не строка.
Далее, небольшая тонкость касающаяся массивов. В яваскриптах есть названия для классов объектов — строка, число, массив и, внимание(!), Объект. Так и приходится писать объект объект.
новый массив можно создать например как:
a = new Array(); или в сокращённой нотации a = [];
новый Объект (буду писать с большой буквы), можно создать так:
a = new Object(); или в сокращённой нотации a = {};
в объект массива — [] — мы можем записывать только числовые, строковые и булевы переменные. Ну и другие массивы тоже. В объект Объекта — мы можем записывать то же самое + функции. Пример:
var a = {1,2,3, 'my_func': function(){ do_something; } };
Обращу внимание, что функция будет доступна как элемент массива: a['my_func'](); и как метод объекта a.my_func(); — в принципе равнозначно, как кому нравится.
Теперь внимание — массив, может содержать индексы элементов, т. е. на какой позиции какая переменная находится. В яваскриптах массив может содержать только ЧИСЛОВЫЕ индексы. В то время как объект — может содержать любые индексы переменных.
Индексы в записи Объекта пишут так index:value, однако это не подходит для записи массива (спасибо SelenIT в комментариях), поэтому запись
a= [1:'something', 2:'something']; — НЕ верна
a= ['first':'something', 2:'something']; — НЕ верна
a= {'first':'something', 2:'something'}; — верна
Теперь я расскажу о функциях. Функции — так же как и строки, и числа, и Объекты, являются в какой-то степени объектами. Они, согласно моему определению «объект — это данные + функции» — могут содержать набор данных, и (!) функций.
Отличия от строк — и т. п. — в том что чтобы вызвать внутреннюю функцию функции, или же переменную объявленную внутри функции необходимо вызвать саму функцию, объявляются внутри с помощью кодового слова this. Вся эта конструкция выглядит так:
function test(){
// do_something;
this.x = 5;
}
тогда a = test().x; // равно 5
функция при этом выполняется, и может что-то делать:
<script>
function test(){
// do_something;
alert('test');
this.x = 5;
}
a = test().x;
</script>
присвоит переменной число 5 — и покажет alert().
Ссылки на объекты
В заключение, мне хочется в очередной раз рассказать об одной особенности языка Javascript связанной с операцией присваивания.
Когда происходит присвоение переменной строки, числа или логической переменной, это создаёт копию этого значения. В то время как присваивание переменной массива или объекта создаёт ссылку на это значение. Это вызывает путаницу, т. к. оказывается что изменение одной копии массива изменяет и вторую когда не надо, и наоборот когда надо присваивание свойства элемента переменной не изменит его с изменением этого свойства.
Пример:
a=document.title; // Присваиваем переменной a - значение заголовка документа a='test'; // присваиваем переменной другое значение, заголовок документа не меняется a=document; // присваиваем переменной значение документа a.title='test'; // присваиваем заголовку значение - меняется заголовок окна.
P.S. Так же очень хочу сказать что Джон Ресиг (создатель jquery если кто не в курсе), недавно выступил с отличной и правильной идеей преподавания javascript в качестве первого языка программирования. Пожалуйста прочитайте его статью: Яваскрипт как первый язык программирования.В ней он так же затрагивает некоторые вопросы методологии, и как и я подчёркивает то, что в яваскриптах всё, включая функции является объектами. Цитирую:
Function Declarations
Perhaps the most interesting change that we can make is a rather subtle one, but it's eschewing normal function declarations for creating anonymous functions and assigning them to a variable.
// Don't do this:function getData(){}// Do this instead:var getData = function(){};
There are a number of good habits that are instilled when you use this particular technique.
Makes it easier to understand "functions as an object". I've found that when you show new developers a function being assigned to a variable it suddenly becomes much more obvious that a function is actually an object and can be manipulated as such (and that a function can be passed as an argument to another function). Thus students are advanced along the path towards a better understanding of functional programming.
Почти полтора месяца писала данную статью, но надеюсь оно того стоило. Данная статья может выглядеть холиварной, поэтому не спешите писать комментарии пока не прочитаете полностью. Статья главным образом о методологии.
Дело в том, что я твёрдо уверена, что в учебных заведениях по информационной специальности, школьникам и студентам забивают голову историей древнего мира вместо актуальных знаний. Все методички преподают дамы бальзаковского возраста, а пишут эти методички профессора возраста Карла Маркса. В результате от соискателей на работу, и от стажёров, я слышала такие забавные заблуждения, относительно фундаментальных основ, как:
в байте 1024 бита
в байте 8 бит потому что 8 — степень двойки
бит принимает всякие разные значения от 0 до 1
В числе прочих забавных случаев: для выбора десяти случайных чисел из бд, соискатели десять раз делают запрос; для открытия файла на чтение используют в PHP флаг 'a+'; не умеют работать со строками, кодировками и указателями. Написать функцию, которая возвращает строку задом наперёд, не используя переменную-буфер — вообще непосильная задача.
В этой статье, я хочу коснуться проблемы заблуждений с битами и байтами, и написать свою методику обучения этим фундаментальным знаниям.
Долго не писала, не отвечала на коментарии, и гостевую — была в отъезде.
В предыдущем посте (Zend Guard пролетел…), коллега Bars задал вопрос, как быть если просят открыть код, до оплаты проекта, и как работать с западными заказчиками.
О геополитике
Сперва, немного проясню, читателям блога, и тебе, уважаемый Bars, что как и где. Самая благоприятная атмосфера для работы по сайтостроению сейчас в России, здесь очень большой спрос на сайты, который щедро оплачивается, особенно в Москве, даже мы иногда аутсорсим часть работы украинским коллегам. Средний российский фрилансер работает на Москву. Поскольку мы работаем с заказчиками тоже исключительно в Москве, они приезжают в офис, пьют кофе и все проблемы легко решаются.
Сложнее обстоят дела на Украине, откуда судя по всему и пишет тов. Bars. Украинский внутренний рынок сайтостроительства вообще не насыщен, особенно по дизайнам (пруф. ищите ссылки на интервью А.Лебедева). Т. е. ситуация такая, что свой, украинский заказчик, не может платить столько, сколько платят на западе, например. Поэтому на Украине более развито направление работы с западными заказчиками. Работа на внутреннем рынке ведётся, но пока медленно. Украинские компании пока вообще не понимают, зачем им сайты. Билл Гейтс со своей книжкой «Бизнес со скоростью мысли» видимо уже 12 лет никак не попадёт на книжные лавки Киева. А жаль. Зато именно украинским дизайнерам мы обязаны такому обилию шаблонов на западных темплейт-стоках.
Совсем тяжко сейчас в Белоруссии (Беларуси). Батька запретил всё, что только можно. Знакомые минчане очень переживают. Все банковские транзакции перекрыты. Перевод валют не осуществляется. Даже банк «Москва-Минск» не совершает переводов Москва-Минск! О кризисе внутренней насыщенности белорусского рынка, можно понять, просто посмотрев на сайт того же банка — http://www.mmbank.by/. А потом, для сравнения, на не самый лучший сайт Банка Москвы http://www.bm.ru/.
В странах Европы, ситуация поздоровее. Люди работают и на внутренний и на западный рынок.
Как вести себя с заказчиками
Статьи с примерно таким заголовком вам нужно читать в больших количествах. Легко отличить хорошие статьи от плохих, но прочитать критически стоит почти все. Также полезно практиковаться в риторике и прикладной психологии. Но самое полезное — это завести себе крутого менеджера, если у вас его ещё нет. Если вы делаете сайт один — то менеджер должен просить никак не меньше 30–50% с заказа, или он просто не понимает своих задач.
Далее, что касается закрытости кода. Конечно можно его обфусцировать, но почти вся обфускация сводится к "$blablabla=blablabla; eval($blablabla);"т. е. эффективность ноль. Как правильно начал делать тов. Bars в своей статье — сайт нужно показывать на своём хостинге. И никуда его не устанавливать до тех пор пока вам не будет переведена вся сумма в полном объёме. Если заказчик из СНГ, и вообще производит впечатление приличного человека, можно пойти на уступки и заранее оговорить, что после демонстрации на своём хостинге он оплачивает 66% стоимости, тогда он будет уверен, что вы перенесёте сайт, а для вас остаток как раз и будет той платой за труды по переносу. Услуги по переносу желательно сразу включать в общую стоимость (и уточнить заказчику что это не 5 минут обычно, а больше). Хорошей практикой будет полностью оплачивать хостинг сайта (на пару недель), а потом передавать сайт прямо с этим хостингом — заказчик не будет нервничать, что-то сломается.
У нас не утопия. Если у заказчика будет большой соблазн кинуть — он кинет. Настройте себя на эту мысль. Достаточно один (иногда два =)) раза наступить на грабли кидания, чтобы понять, в какой момент передавать свой код. Код, который вы уже написали — больше всего нужен заказчику, а не вам. Если заказчик не хочет платить — не отдавайте код. Умный заказчик купит готовый продукт охотнее и дороже, чем будет ждать разработки с нуля. Потому что пара недель простоя его бизнеса стоит гораздо больше, чем ваша пара недель. Он может ругаться, но не может не заплатить. Иначе убытки будут у него, а не у вас. Это основная идея — запомните её и никаких проблем не будет.
Итак, в статье о том как настроить opensearch, я упомянула, о том, что поисковые подсказки в формате json можно использовать и на сайте. Давайте посмотрим как это сделать.
Поскольку я каждый раз после переустановки системы забываю где искать, напишу заметочку здесь.
Начиная с 8й версии Adobe Photoshop в проводнике windows больше не показывается превьюшек для PSD файлов, это неудобно когда вам нужно видеть какой из файлов открыть.
Однако есть способ восстановить превью к PSD файлам, как это было в версии PS 7.
Библиотека для просмотра превьюшек (psicon.dll) к .psd не включена в состав программы, поэтому её нужно скачать отдельно, например с моего сайта, вот инструкция по установке:
Итак, сегодня перед нами с коллегами встала задача сделать систему резервного копирования всех php файлов. Большое спасибо Axel и mr.troll за составление данной статьи.
После проб и ошибок представляем результат (протестировано на системах типа redhat):
cd /hosting && -переходим в папку, в которой будем искать пхп файлы.
find ./ -name *.php - ищет собственно php файлы в этой папке, можно искать несколько расширений через ключ -regex, но эти регулярные выражения несколько отличаются от обычных, поэтому мы всё таки остановились на данном простом варианте.
-exec tar ... '{}' + - в процессе выполнения, команда find запускает собой команду tar, где вместо '{}' - попадает имя файла, как вариант можно запускать через конструкцию "| xargs ".
-upvf - ключи к команде tar, важно знать что команда tar вызывается не для всех значений сразу, поэтому нужноиспользовать ключ "u" - который добавляет новый файл в архив, а не "с" - который создаёт каждый раз новый, иначе в архив попадут всего несколько найденных файлов. Также нельзя сразу использовать ключ "z" для архивирования, т.к. tar не умеет дописывать в архивы. Ключ "p" - опционален, сохраняет права файлов.
/backup/phpfiles/php_files_`date +%Y-%m-%d`.tar - имя файла куда сохранять бекап, с командой date - можно сохранять отдельные архивы каждый день.
> /dev/null - для очистки стека от сообщений вывода команд, иначе все сообщения будут мусорить в логах сервера.
gzip - архивируем для экономии места.
Запускать это проще, сохранив скрипт в sh-файл (без решёток в начале строк) и поставив права на запуск для пользователя.
Владельцы сайтов и хостингов легко могут экстраполировать данный скрипт на работу с конкретными папками пользователей, если вместо /hosting - писать папку пользователя "~". После скрипт помещаем в кронтаб пользователю и вуаля...
Для бекапа файлов по всему серверу, как написано выше засовываем это в кронтаб рута. Помните о безопасности и не оставляйте прав на чтения бекапов для посторонних пользователей!
Итак, для тех кто не использует ночные сборки Файрфокса, будет новостью, что в последних версиях лисички не работают редиректы с включенным расширением Adblock (bug 23092).
Казалось бы, что может быть важного в редиректах? Однако ньюансы программирования таковы, что часто для попадания на какую-то страницу нужно пройти через ряд промежуточных. Это касается поиска, авторизации и т.п. отправки форм.
Хочу поделится результатами пользования популярными сервисами с отключенными редиректами.
У mail.ru вроде бы всё работает. по крайней мере почта и поиск
у рамблера работает авторизация на почту, но не работает поиск
у гугла наоборот, работает поиск, но не работает авторизация в гмайл
у яндекса не работает вообще ничего. Что не удивительно, ведь "поисковик №1" всегда отличался пренебрежением к веб-стандартам и удобству пользователя.
на любимом хостинге Jino.ru, не работает регистрация.
Недочёты есть и в авторизации PhpMyAdmin, и в шаблонах страниц nginx'а.
Под словом "работает" я подразумеваю. что или редиректов не используется, или каждый редирект дублируется ссылкой, которую можно нажать. Соответственно "не работает", когда видно только пустую страницу, или вообще что-то невнятное (как в случае с авторизацией на яндексе).
Я призываю веб-мастеров прошерстить свои движки на предмет дублирования редиректов соответствующими ссылками. Даже в движке моего бложика были проблемы с авторизацией, которые оперативно устранились.
Поскольку с версии 3.7, любимое мной расширение Nightly Tester Tools больше не работает, то форсированно запускать остальные расширения на бета-версии файрфокса стало проблемой.
Не так давно Mozilla решила что будет лучше изменить для пользователей способ форсировать расширения для работы с новыми версиями Firefox, что введено уже в последнем релизе Firefox 3.6. Раньше вы могли выставить для всех версий файрфокса в свойствах about:config настройку extensions.checkCompatibility в значение false. Теперь название этой настройки немного изменилось.
Вам нужно будет немного менять его для каждого шага разработки Firefox (alpha, beta, release, и т. п.).
В адресной строке наберите: about:config
Кликните в любом месте страницы и выберите New -> Boolean
Имя настройки, которое вам нужно, зависит от того, какую версию Firefox вы используете, например:
Firefox 3.6: extensions.checkCompatibility.3.6
Firefox 3.7 Alpha: extensions.checkCompatibility.3.7a
Firefox 4.0 Beta: extensions.checkCompatibility.4.0b
Firefox 9.0: extensions.checkCompatibility.9.0
Для Firefox Nightly всех версий начиная с 7: extensions.checkCompatibility.nightly
Установите её значение в false чтобы заставить браузер отключить проверку совместимости ваших дополнений с вашей версией Firefox.
Решение о том чтобы не делать одинаковое имя настройки понятно. Многие пользователи включают её один раз и забывают о ней, тогда как браузер и расширения развиваются, наступит момент когда имеющиеся старые расширения не будут работать, в них может окажеться уязвимость, или они приведут к нестабильности работы браузера. Если пользователь собственноручно обновляет эту настройку в конфиге, от релиза к релизу, то значит он берёт ответственность за то какие несовместимые расширения он использует.
UPD: Для ночных сборок Файрфокса начиная с Firefox Nightly 7.0, введена единая настройка extensions.checkCompatibility.nightly