JavaScript. Создание объектов

    JavaScript предоставляет разработчикам возможность создавать объекты и работать с ними. Для этого существуют следующие приёмы:
    • Оператор new
    • Литеральная нотация
    • Конструкторы объектов
    • Ассоциативные массивы



    Используем оператор new



    Это, наверное, самый легкий способ создания объекта. Вы просто создаете имя объекта и приравниваете его к новому объекту Javascript.


    //Создаем наш объект
    var MyObject = new Object();
    //Переменные
    MyObject.id = 5; //Число
    MyObject.name = "Sample"; //Строка
    //Функции
    MyObject.getName = function()
    {
        return this.name;
    } 
    


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


    //Используем наш объект
    alert(MyObject.getName()); 
    


    Литеральная нотация



    Литеральная нотация является несколько непривычным способом определения новых объектов, но достаточно легким для понимания. Литеральная нотация работает с версии Javascript 1.3.


    //Создаем наш объект с использованием литеральной нотации
    MyObject = {
        id : 1,
        name : "Sample",
        boolval : true,
        getName : function()
        {
            return this.name;
        }
    } 
    


    Как видите, это довольно просто.


    Объект = {
    идентификатор : значение,
    ...
    } 
    


    И пример использования:


    alert(MyObject.getName()); 
    


    Конструкторы объектов



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


    function MyObject(id, name)
    {
    
    } 
    


    Только что мы написали конструтор. С помощью него мы и будем создавать наш объект.


    var MyFirstObjectInstance = new MyObject(5,"Sample");
    var MySecondObjectInstace = new MyObject(12,"Othe Sample"); 
    


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


    Как и в ООП, у MyObject могут быть методы и различные свойства. Свойствам можно присвоить значения по умолчанию, либо значения, переданные пользователем в конструкторе объекта.


    function MyObject(id, name)
    {
        //Значения переданные пользователем
        this._id = id;
        this._name = name;
        //Значение по умолчанию
        this.defaultvalue = "MyDefaultValue"; 
    } 
    


    Аналогичным образом мы можем создавать и функции.


    function MyObject(id,name)
    {
        this._id = id;
        this._name = name;
        this.defaultvalue = "MyDefaultValue"; 
        
        //Получение текущего значения
        this.getDefaultValue = function()
        {
            return this.defaultvalue;
        }
        
        //Установка нового значения
        this.setDefaultValue = function(newvalue)
        {
            this.defaultvalue = newvalue;
        }
        
        //Произвольная функция
        this.sum = function(a, b)
        {
            return (a+b);
        }
    } 
    



    Ассоциативные массивы



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


    var MyObject = new Number();
    MyObject["id"] = 5;
    MyObject["name"] = "SampleName"; 
    



    Для обхода таких объектов можно использовать такой цикл:


    for (MyElement in MyObject)
    {
        //Код обхода
        //В MyElement - идентификатор записи
        //В MyObject[MyElement] - содержание записи
    }
    



    По материалу подготовлена небольшая схема.





    Вы можете её посмотреть в форматах: PNG SVG


    Огромное спасибо gro за помощь.
    Поделиться публикацией

    Похожие публикации

    Комментарии 81
      +2
      Всё-таки пример с ассоциативными массивами не совсем корректен. Есть порядковые массивы, которые по совместительству, так же как и многое другое, являются объектами.
      Совершенно аналогично будет:

      var MyObject = new Number();
      MyObject["id"] = 5;
      MyObject["name"] = "SampleName";
        0
        Ага, добавил.
          –4

          var MyObject = new Number();
          MyObject["id"] = 5;
          MyObject["name"] = "SampleName";


          пацталом :D зачем писать, если не разбираешься в предмете?
        +1
        Великолепно! В закладки, да и кармы прибавил :)
          0
          Стоящая работа — добавил кармы. Огромное спасибо!
            0
            В javascript нет никаких ассоциативных массивов! Что вы такое городите?
              0
              Это название приёма
                +1
                Ассоциативный массив — это такой тип данных, хэш-таблица. Для создания хэшей в javascript используется Object. Использование Array в вашем случае — не пришей кобыле хвост. Почитайте первый комментарий от gro.

                К примеру, для того, чтобы определить количество элементов массива, есть Array#length. А в вашем случае как определить?
                  0
                  Это эмуляция отсутствующего типа данных.
                0
                В избранном! Кармы, к сожалению, пока добавить не могу (
                  +2
                  var MyObject = new Object();
                  var MyObject = new Array();
                  var MyObject = new Number();

                  Какая нафиг разница? Почему просто не написать, что что угодно из этого может выступать ассоциативным массивом? И что для них тоже используется литеральная нотация? Только запутываете читателей.
                    0
                    Это все - хеши
                      0
                      Именно так.
                    0
                    Людям, которым понравилось, или впервые увидели, думаю будет занятно почитать Дмитрия Котерова:
                    http://dklab.ru/chicken/nablas/39.html
                    0
                    Хороший пост, спасибо.
                      0
                      Хорошая статья, спасибо!
                        0
                        ИМХО, каждую статью о ООП наужно начинать с того, что в JS нет наследования на основе классов, а есть делегирование на основе прототипов. Не надо даже пытаться их равнять. Так проще читающим. Вроде "забудь о том, что знаешь о ООП, тут оно другое!"
                          +2
                          А здесь вообще про ООП практически ничего нет. Здесь есть работа с объектами.
                            +2
                            Простите а "работа с объектами" это разве не ООП? :) Как минимум полиморфизм тут представлен. Ничего не сказано про и инкапсуляцию, наследование (которых по сути и нет в JS) и создание классов - это да, хотя пример "класса" (конструктора) все таки присутствует.
                              0
                              Инкапсуляция и наследование "по сути" есть в JS. А вот "классов" нет.
                                0
                                Это почему инкапсуляции нету? Объект сам по себе суть "купсула" независимо от языка и подхода.
                                  +1
                                  Инкапсуляция это, когда у объекта есть свойства к которым только он имеет доступ, то есть доступ к этим свойствам можно получить только через специальные методы (set/get) или не получить вообще.
                                  определение с вики:
                                  Инкапсуля
                                    0
                                    (отчего-то обрезалось)
                                    Инкапсуляция — свойство языка программирования, позволяющее объединить данные и код в объект и скрыть реализацию объекта от пользователя. При этом пользователю предоставляется только спецификация (интерфейс) объекта. Пользователь может взаимодействовать с объектом только через этот интерфейс.
                                      0
                                        0
                                        Во-первых, она есть в JS, ссылку дал Дед Мороз.
                                        Во-вторых, инкапсуляция в своей основе — объединение вместе данных и кода, обрабатывающего их. Сокрытие это дополнительная фишка в некоторых реализациях ООП, к самой сути инкапсуляции отношения не имеет.
                                        Python, например, весь из себя объектный, намного более чем то же C++, а сокрытия там вообще никакого нет.
                                          0
                                          Вот не соглашусь с вами. В примере DeadMoroz'а используются замыкания, и для каждого экземпляра будут создаваться свои экземпляры метода (функции). Таким образом, получаем больший расход памяти и потерю скорости на создании методов (особенно если методов много). К тому же совсем не используется механизм прототипов, и мы не сможем "унаследовать" новый "класс" от данного. Ну и еще неприятный момент - невозможность расширить ваш класс/конструктор (хотя конечно есть пара тройка извращенных способов).
                                          И все таки инкапсуляцию - это скрытие реализации объекта, так чтобы никто не мог поменять критическое свойство или прочитать его - случайно или намерено. В следующей версии JS как раз такая возможность появится (создавать приватные свойства и методы).
                                          Отсутствие сокрытия - скорее зло чем добро, потому как "разломать" объект (сложнее чем набор свойств) ни составляет труда, и все зависит от программиста. И часто бывает что "ломают" объекты случайно, и только потому что какое нибудь свойство не скрыто, а его меняют.
                                            +1
                                            Да, использование замыканий это неуклюжая калька с "обычного" ООП.
                                            В "обычном" ООП "физически" объект ни от чего не защищён. Он защищён "условно". Ничто не мешает добавить условность и в js. Например, обычное соглашение об именах: префикс "__" для защищённых объектов. "Ошибиться" и сломать "случайно" какое-нибудь object.__protectedProperty невозможно.
                                              0
                                              * замыканий для защиты свойств.
                                                0
                                                Как это физически не защищён? Он защищен на уровне компилятора/интерпретатора обычно (кроме страшных хаков). Насколько "физичнее" по вашему должна быть защита?
                                                  –1
                                                  "Условная защита" значит, что народ _договорился_ не трогать защищённые члены.
                                                  А чтобы _случайно_ не накосячить, проверку возложили на компилятор. Проверку.
                                                  Если же кто-то _захочет_ поломать объект, он его поломает.
                                                  И, раз уж защита строится на договорённости, почему в js должно быть по-другому?
                                                  Как "случайно не накосячить" я уже привёл пример.
                                                  0
                                                  А в чем неуклюжесть? Кроме шуток.
                                                    0
                                                    lahmatiy написал чуть выше, в первом абзаце.
                                                  0
                                                  Для методов да. Для свойств вполне.
                                                  Если пытаться дословно перенести "классическое" ООП на "прототипное", пытаясь использовать прототипы точно так же как классы, а замыкание только для закрытия свойств в том же виде, в каком это присутствует в классах.
                                                  Однако, если отрешится от всего что мы прочитали в книжке "ООП на C++" и попытаться осознать парадигму JS с самого начала, то окажется, что там есть и инкапусляция, и полиморфизм, и наследование. И использовать их очень удобно и на скорость и память это не слишком влияет. Только писать код нужно совершенно по другому.
                                                  Отсутствие сокрытия - скорее зло чем добро

                                                  Это тема для длительных дискуссий (и их тьма). И я здесь скорее на вашей стороне. Однако, это не относится к тому факту, что инкапсуляция без сокрытия, это та же инкапсуляция.
                                                    0
                                                    Перечитал, что написал :) Второй абзац должен был заканчиваться чем то вроде "в каком присутствует в классах, то, действительно, получится полная фигня".
                                      +1
                                      Все что в JavaScript - это объекты, и работать надо с ними так же как с объектами, т.е. тут нету массивов, строк и т.п.

                                      например: var myString = "я строчка";
                                      так вот myString это тоже объект, который имеет свои методы и может быть расширен новыми вашими методами, за это я кстати и люблю JS.
                                        0
                                        Покажите пример расширения примитивной строчки (именно данной переменной, а не прототипа String)
                                          0
                                          естественно я имел ввиду String, не надо придираться. В любом случае
                                          при записи var myString = "я строчка"; myString сразу становится объектом String, который и можно расширять (естественно через prototype)

                                          пример:
                                          String.prototype.getBold = function() {
                                          return "<b>" + this + "</b>";
                                          }

                                          var myString = "test";

                                          document.write(myString.getBold());
                                            +1
                                            Не становится.
                                            myString содержит примитивное значение.
                                            При использовании с ним "объектного синтаксиса" (myString.getBold) создается "объект-над-примитивом", который и используется.
                                            Например, установить свойство для myString не получится:
                                            myString.x = 10;
                                            alert(myString.x); // undefined
                                              0
                                              ну я писал про методы и не свойства, в любом случае данный пример можно осуществить следующим образом:

                                              String.prototype.x = null;
                                              String.prototype.SetX = function(intValue) {
                                              String.x = intValue;
                                              }

                                              String.prototype.GetX = function() {
                                              return String.x;
                                              }

                                              var myString = "test";
                                              myString.SetX(13);

                                              alert(myString.GetX());

                                              Кстати такой вид записи был бы правильнее, чем прямой доступ к свойству x.
                                                0
                                                Правильный, неправильный, это с какой точки посмотреть. У вас всё равно идет прямой доступ к свойству GetX :)
                                                Да и ваш пример опять таки не показывает того, что вы хотите показать. Вы ставите свойство на прототип, то есть на все строки, а не на конкретную.
                                                Смысл в том, что за озарением "в JS всё объекты" у изучающего должно через какое-то время идти "неа, не всё в JS объекты".
                                                  0
                                                  ну так правильно, я работаю со String, поэтому и GetX будет у всех строк. Но все же var myString = "test"; тут myString все же объект, потому что как минимум у него есть свойство length.
                                                  Если же нужно расширять функционал именно для myString, то и создавать тогда myString необходимо по другому;
                                                    0
                                                    Да, создавать нужно так, как показал lahmatiy чуть ниже.
                                                    Вот именно там переменная содержит ссылку на объект. Если вы утверждаете, что в вашем случае так же получается объект, то объясните разницу в поведении этих двух примеров.
                                                    У myString нет свойства length, оно есть у объекта-над-примитивом, появляющегося только в момент выполнения операции.
                                                      0
                                                      а какая разница когда и как обрабатывается свойство length? если бы myString был обычной строкой в полном этом понимании, то не о какой length речи бы и не шло. Другое дело, что примитив myString тоже видимо что то типа объекта, только ущербного :)

                                                      Думаю вы поняли меня, я понял вас, в любом случае ваши знания о JS больше моих, поэтому я приму к сведению весь наш спор :) . Поставил бы + да не могу, первый день тут :)
                                                        0
                                                        Просто данная тема кажется элементарной, а подобный спор спором о терминах или вообще не о чем.
                                                        Однако, большинство программистов, когда начинают более-менее глубоко разбираться в JS, из за неполного понимания подобных фишек набивают себе много шишек ). Чему во многом способствуют авторы большинства книг. Чего только стоит их опусы про "примитивы передаются по значению, а объекты по ссылкам".
                                                0
                                                Да, тут поможет только
                                                var myString = new String('some str');
                                                или
                                                var myString = new Object('some str');
                                                только в этом случае typeof myString будет возвращать 'object' и в этом случае проверить что это строка можно только myString.constructor === String
                                          +2
                                          Вот что с людьми делают фреймворки (prototype, jQuery etc) - они не знаю основные принцы построения объектов в JavaScript :( хотя тут скорее не построение, а обычная работа с объектами.

                                          Замечания:
                                          1. my_object.property == null проверяет не присутствие свойства, а равно ли null (или undefined) свойство property объекта my_object.

                                          var my_object = { property: null };
                                          my_object.property == null; // вернет true: свойство и правда равно null
                                          'property' in my_object; // вернет true: это свойство есть у объекта
                                          'absent' in my_object; // вернет false: этого свойства нет у объекта

                                          таким образом проверка существования свойства производится не сравнением свойства с null, а конструкцией 'property_name' in object
                                          (данная конструкция не работает в старых версиях IE, если не ошибаюсь до версии 5.5)

                                          2. delete может удалять и свойства и сами объекты. По сути имена объектов/свойств это всего лишь ссылки, так что в данном случае удаляется ссылка на объект (ассоциация с объектом), а если ссылок на объект больше нет, то и сам объект разрушается (срабатывает сборщик мусора).

                                          var a = { p: 'value' };
                                          var b = a;
                                          alert(typeof a); // object
                                          alert(typeof b); // object
                                          delete a;
                                          alert(typeof a); // undefined
                                          alert(typeof b); // object
                                          delete b;
                                          alert(typeof a); // undefined
                                          alert(typeof b); // undefined


                                          3. Нет разницы между следующими записями
                                          my_object.name = 'value';
                                          my_object["name"] = 'value';
                                          вторая запись используется только тогда, когда имя свойства противоречит правилам именования переменных, т.е. содержит символы не разрешенные в именах переменных (то есть символы за исключением a-z, A-Z, 0-9, _ (знак подчеркивания), $ (знак доллара) ) или имя свойства начинается с цифры.
                                          Вы пишите "значения соотвествуют object['name'] == object.name"
                                          это то же самое что написать object == object, странно будет тут получить false.

                                          4. Конструкции new String(), new Boolean(), new Number() создают объекты типа 'object', так что получается такая картина

                                          var str1 = new String('str');
                                          var str2 = 'str';
                                          var str3 = str2;
                                          typeof str1; // object
                                          typeof str2; // string
                                          str1 == str2; // true - примитивные значения равны
                                          str1 === str2; // false - эти переменные ссылаются разные объекты
                                          str2 === str3; // true - эти переменные ссылаются на один объект

                                          в тоже время только new Function() возвращает объект типа function
                                          так что будьте осторожны, лучше использовать "скрытые" конструкторы (как в случае с str2).

                                          и т.д.

                                          ЗЫ:
                                          Instance != инстанция
                                          Instance == экземпляр класса (объекта)
                                            0
                                            >2. delete
                                            Вот вы пример пишите, а проверить? Там везде будет object. Удалять можно только свойства объектов, но не переменные.
                                            Вернее можно удалить "глобальные" переменные, объявленные без "var", так как они и не переменные на самом деле, а свойства глобального объекта.
                                              0
                                              Да, Вы правы. Проверял в консоле firebug, и он немного "обманул". Глобальные объекты удаляются (как удаление свойства у window), хотя у IE есть известная проблема с этим (там не всегда можно удалить).
                                              0
                                              Конструкция new String() создает объект именно "типа" String. "Наследованный" от Object, но не тождественный ему. В нем содержится предопределенный набор методов для работы со строками, не имеющийся в Object и неявная связь ([[Value]]) с примитивными значением.
                                                0
                                                Отличный коментарий :)

                                                Я даже задумался над тем чтобы написать статейку про "замыкания" (closures). Чтобы затем в итоге получить такой дополняющий пост.
                                                Если осилю, дам знать ;)

                                                А так конечно, нового мало в статье написано, но при наличии богатых коментариев даже неновый и не эксклюзивный материал приносит неплохую пользу!
                                                Так что, автор, если в следующий раз будете сомневаться писать или нет, то пишите :)
                                                Уж, на нынче подхламленном хабре хуже от этого точно не станет :D
                                                  0
                                                  Пишите, тема довольно сложная, потому как многие часто используют неправильно/неоправданно (спасибо prototype за bind) и ловят неожиданные результаты (ошибки/неправильную работу), не понимая почему так.
                                                  Тут уже выше давали ссылку на статью Котерова по этой теме: Большие хитрости JavaScript
                                                0
                                                Ниачом! Профессионалы будут плеваться (собственно что и происходит, и я их поддерживаю), а новичков только запутает. Правильно советовали люди выше — читайте наблы Димы Котерова, он как никто хорошо объяснил в своих статьях что есть объекты в JavaScript и как с ними работать.
                                                  0
                                                  Да. Если не считать множества неточностей и вообще ошибок в его объяснении.
                                                  0
                                                  ну раз речь об объектах пошла, то можно сказать пару слов про закрытые функции и свойства :)

                                                  myClass = function () {
                                                  var _privateProperty = '';
                                                  var _privateFunction = function() {
                                                  }

                                                  this.publicGetter = function() {
                                                  return _privateProperty;
                                                  }

                                                  this.publicCallPrivate = function() {
                                                  return _privateFunction();
                                                  }

                                                  }
                                                    0
                                                    Ну так скажите пару слов :)
                                                    Хотя бы дайте ключевое слово ("замыкание"), чтобы начинающим читателям было куда копать :)
                                                      0
                                                      пардон, если подробнее, то ява скрипт поддерживает такой механизм как "замыкания"

                                                      за счёт которого можно реализовать закрытые и открытые методы "классов"
                                                      подробнее: теория, для javascript можно изучить вопрос здесь, издесь
                                                  +1
                                                  поразительно! статья об Обьектах в JS и ни одного слова " prototype ". *откашливаецо*
                                                    0
                                                    за что я люблю хабру, так это за то, что кроме полезной статьи (такие бывают :)) в комментах пишут ооочень много полезного (иногда больше полезного чем в самой статье), так что товарищи, читаем комменты и мотаем на ус.
                                                      +3
                                                      Я смотрю, http://sphere.habrahabr.ru/blog/28641.ht… прошла лесом.
                                                        +1
                                                        вы б ее в коллективный блог добавили...
                                                          0
                                                          Перенёс.
                                                          0
                                                          а ваша статья на мой взгляд лучше :) гораздо :)

                                                          хотя рулит конечно же крокфорд%))
                                                        • НЛО прилетело и опубликовало эту надпись здесь
                                                            +1
                                                            Котеров не писал не здоровой херни. Он написал статьи, которые вызвали интерес к JS среди широких кругов. А так как в них были фактические ошибки, то они породили интересные дискуссии, в следствии которых у многих так же повысилось знание JS.
                                                            Так и данная статья, возможно не несет конечного знания, но породило достаточно интересную беседу, после бесконечных матерных частушек и остальных "служить ли ИТшникам в армии".
                                                            Вы бы могли бы присоединиться к ней и просветить все 80% дебилов насчет этого удивительного языка.
                                                            • НЛО прилетело и опубликовало эту надпись здесь
                                                                0
                                                                Ваш ответ фееричен. Он совершенно точно отражает ваш статус на данном ресурсе и репутацию.
                                                                • НЛО прилетело и опубликовало эту надпись здесь
                                                                    0
                                                                    Своя не значит. Но получить усредненное представление о собеседнике по ней можно.
                                                                    • НЛО прилетело и опубликовало эту надпись здесь
                                                                        0
                                                                        Как самоцель — торчать на сайте, только ради набирания этих цифорок, чтобы потом ими мерятся с другими, мне не интересно.
                                                                        Но как побочное явление, позволяющая сделать первое мнение о собеседнике, очень полезно. Например, первое мнение о вас подтвердилось со всей точностью. Вы из тех людей, про которых дедушка Фрейд говорил, что их в детстве напугали большим членом.
                                                            0
                                                            Статья, конечно, хорооошая... но не для тех, кто давно кодит на JS, а так... для тех, кто на нем не кодит и кодить не будет :). Пусть дивятся и радуются.

                                                            Для людей, которые действительно хотят научиться нормально программировать на жаваскрипте, рекомендую книжку:

                                                            AJAX в действии (Дейв Крейн, Эрик Паскарелло, Даррен Джеймс)

                                                            http://www.internet-technologies.ru/books/book_194.html


                                                            Обратите внимание на приложения в конце книги. Там коротко и ясно описано: что такое обьекты в JS, как их создавать и многое другое.
                                                              0
                                                              Всё новое - хорошо забытое старое. Ничего нового в статье не увидел.
                                                                0
                                                                ага ;)
                                                                this[block ? 'block_fields' : 'fields'][name_fields[i]][disable ? 'disable' : 'enable']();
                                                                  0
                                                                  К чему вы это?
                                                                  Опять пропагандируете тернарный оператор? :)
                                                                    0
                                                                    %) ну что поделаешь. В даном случае просто как пример того, что не только дотнотация this.that.do() в ходу...
                                                                    т.е. вместо if (block) { this.block_fields() } else { this.fields() } можно использовать лаконичное this[block ? 'block_fields' : 'fields'](); А можно и не использовать (для тех, кто не любит читать тернарные операторы)!
                                                                    0
                                                                    мой код и так сложно читать, а если я начну писать так, что я стану незаменимым работником :)
                                                                      0
                                                                      ;) ну дык, совмещение работы и развлечения (решение логических задачек на скорость)
                                                                    0
                                                                    Спасибо, хорошая статья!

                                                                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                                    Самое читаемое