Для комментариев зарегистрироваться или войти
Либо используйте ваш Open_ID, например аккаунт гугл, яндекс или ЖЖ
 

30 декабря 2011.  Объекты, объекты-объекты; объекты? Объекты!

Зомби зомби зомби. © Народная мудрость
Developers! Developers! Developers! Developers! © Stiven Ballmer

Речь в сегодняшней статье пойдёт в основном о яваскриптах, потому что именно их я преподаю сейчас стажёру нашей компании. Поэтому статья носит в основном методологический характер.

Что такое объект?

Поскольку яваскрипт, в общем-то объектно-ориентированный язык, мы повторяли определение что же такое объект в программировании и в яваскриптах в частности. Поискав для сравнения определения в интернете я ничего хорошего не нашла. Во всех источниках упоминается полнейшая чушь, что становится конечно понятно откуда берётся каша в головах студентов, соискателей, и стажёров. Потому что, вместо того чтобы делать знания простыми и понятными методологисты переписывают одни и те же книжки каждый раз только запутывая формулировки. Впрочем к концу статьи, я думаю вы запутаетесь сами =). Пока процитирую некоторые определения из википедии:

Объект — Сущность в адресном пространстве вычислительной системы, появляющаяся при создании экземпляра класса или копирования прототипа (например, после запуска результатов компиляции и связывания исходного кода на выполнение).
Википедия

Заметьте, в довольно простое определения навязали адресное пространство, компиляцию, классы и прототипы. Это всё равно что спросить что такое птица, а в ответ получить что это сущность употребимая в пищу и вылупляющаяся из яиц!

Объект — некоторая сущность в виртуальном пространстве, обладающая определённым состоянием и поведением, имеет заданные значения свойств (атрибутов) и операций над ними (методов). Как правило, при рассмотрении объектов выделяется то, что объекты принадлежат одному или нескольким классам, которые в свою очередь определяют поведение (являются моделью) объекта. Время с момента создания объекта (конструкция) до его уничтожения (деструкция) называется временем жизни объекта

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

Объект — это сущность, которой можно посылать сообщения, и которая может на них реагировать, используя свои данные. Данные объекта скрыты от остальной программы. Сокрытие данных называется инкапсуляцией.

Опять таки. В определении говорится об инкапсуляции. А что если данные объекта не скрыты? В прочем поскольку моя статья про яваскрипты, данное определение вообще никакой смысловой нагрузки не несёт.

Объект в программировании, это такая штука, которая не всегда может иметь визуальное представление, типа кнопки или поля. Скорее наоборот.
Представь себе массив — упорядоченный набор переменных. Каждая переменная в обычном массиве может содержать строку, число, (любую типизированную переменную) или другой массив. Поэтому моё определение звучит так:

Объект — это массив, который может содержать в качестве переменных, кроме всего прочего, функции или другие объекты.

Такое определение я призываю запомнить стажёров, потому что это именно то, с чем мы работаем в яваскриптах.

Справедливости ради, хочется так же отметить определение из англоязычной версии. Оно довольно хорошее.

The programming construct that combines data with a set of methods for accessing and managing those data is called an object. © en.wikipedia.org

Т. е. данные, и набор функций (методов) для работы с этими данными называются объектом.

Такой вариант так же допустим для запоминания. А теперь мне хочется рассказать почему яваскрипт это целиком объектно-ориентированный язык, и какие сложности в обучении ему возникают.

Объекты в 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'}; — верна

Но можно создать такой объект

var a = {'вася':'Пупкин'};

и обращаться к нему как к массиву

alert(a['вася']));

Подробнее об этом написано в моей статье «Javascript — работа с массивами и объектами» (09.2009).

Теперь я расскажу о функциях. Функции — так же как и строки, и числа, и Объекты, являются в какой-то степени объектами. Они, согласно моему определению «объект — это данные + функции» — могут содержать набор данных, и (!) функций.
Отличия от строк — и т. п. — в том что чтобы вызвать внутреннюю функцию функции, или же переменную объявленную внутри функции необходимо вызвать саму функцию, объявляются внутри с помощью кодового слова 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'; // присваиваем заголовку значение - меняется заголовок окна.

Об этом, и о том как копировать объекты и массивы, так же написано в моей прошлой статье «Javascript — работа с массивами и объектами».

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.

С удовольствием выслушаю ваши замечания по теме.

Метки данной записи: советы, javascript, методология

14 сентября 2011.  Биты, байты, кодировки

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

Дело в том, что я твёрдо уверена, что в учебных заведениях по информационной специальности, школьникам и студентам забивают голову историей древнего мира вместо актуальных знаний. Все методички преподают дамы бальзаковского возраста, а пишут эти методички профессора возраста Карла Маркса. В результате от соискателей на работу, и от стажёров, я слышала такие забавные заблуждения, относительно фундаментальных основ, как:

  • в байте 1024 бита
  • в байте 8 бит потому что 8 — степень двойки
  • бит принимает всякие разные значения от 0 до 1

В числе прочих забавных случаев: для выбора десяти случайных чисел из бд, соискатели десять раз делают запрос; для открытия файла на чтение используют в PHP флаг 'a+'; не умеют работать со строками, кодировками и указателями. Написать функцию, которая возвращает строку задом наперёд, не используя переменную-буфер — вообще непосильная задача.

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

 

Метки данной записи: советы, методология

Предыдущие записи, смотрите в архиве новостей »

Подпишитесь на статьи через RSS

15 самых популярных статей: