суббота, октября 27, 2007

объекты, хэш-таблицы и яваскрипт

как известно, всё в яваскрипт является объектами.

"как это всё?" - спросит подкованный читатель, - "а как же примитивные типы?"
а примитивные типы - тоже объекты, только несколько иные...

разберёмся с терминологией:
объект - понятие довольно абстрактное, означающее "некая сущность обладающая состоянием и поведением".
примитивные типы в яваскрипте безусловно обладают и состоянием (собственно значение) и поведением (методы, которые они наследуют от своего прототипа)

пытливый читатель может тут возразить, что на самом деле в случае вызова метода примитивный тип просто конвертится в объект, который уже наследует методы. и будет прав! но это не отменяет того факта, что метод-то мы вызываем для переменной содержащей примитивное значение и от состояния этого значения может быть вызван разный метод и дать, соответственно, разный результат.

каждый примитивный тип имеет своё уникальное поведение: при попытке доступа к полям они конвертятся в свои типы объектов и наследуют соответствующий набор полей от прототипа. значит примитивные типы - тоже объекты.

но что в них такого особенного?

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

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

ps: вот что действительно не является объектами, так это значения null и undefined. и это очень печально (-_-)

2 комментария:

Анонимный комментирует...

Ну, вот ты несколько раз сам же и написал про создание объекта НАД примитивным значением и т.д. Всё это лишний раз говорит о том, что фраза "всё в яваскрипт является объектами" не точна, не всё.

Что касается того, что нельзя внутри метода узнать, примитивное значение стояло у истоков вызова метода (через объект) или стоял объект изначально, то это нужно делать ДО вызова метода, а не во время. Потому как, если ты до вызова не знаешь тип значения, то, во-первых, можешь нарваться на null или undefined и получить ошибку, а во-вторых, можно нарваться на несуществующий/чужой метод. В общем, если необходимо знать точно тип, то выявляй его ЗАРАНЕЕ, когда метод уже запустился никаких примитивных значений рядом уже нет, будет поздно.

Пытливый подкованный читатель на букву Z.

Dark-Demon комментирует...

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

null и undefined - действительно примитивные значения. и это очень плохо. Null.prototype мне сть чем расширить, но нельзя (-_-).

касательно "проверки до" - это крайне неудобно. сейчас я выхожу из ситуации так:

var res= $isset( n ) && n.$pow( 2 );