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 за помощь.
    Поделиться публикацией
    Похожие публикации
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 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
                  Людям, которым понравилось, или впервые увидели, думаю будет занятно почитать Дмитрия Котерова:
                  http://dklab.ru/chicken/nablas/39.html
                • 0
                  Хороший пост, спасибо.
                  • 0
                    Хорошая статья, спасибо!
                    • 0
                      ИМХО, каждую статью о ООП наужно начинать с того, что в JS нет наследования на основе классов, а есть делегирование на основе прототипов. Не надо даже пытаться их равнять. Так проще читающим. Вроде "забудь о том, что знаешь о ООП, тут оно другое!"
                      • +2
                        А здесь вообще про ООП практически ничего нет. Здесь есть работа с объектами.
                        • +2
                          Простите а "работа с объектами" это разве не ООП? :) Как минимум полиморфизм тут представлен. Ничего не сказано про и инкапсуляцию, наследование (которых по сути и нет в JS) и создание классов - это да, хотя пример "класса" (конструктора) все таки присутствует.
                          • 0
                            Инкапсуляция и наследование "по сути" есть в JS. А вот "классов" нет.
                            • 0
                              Это почему инкапсуляции нету? Объект сам по себе суть "купсула" независимо от языка и подхода.
                              • +1
                                Инкапсуляция это, когда у объекта есть свойства к которым только он имеет доступ, то есть доступ к этим свойствам можно получить только через специальные методы (set/get) или не получить вообще.
                                определение с вики:
                                Инкапсуля
                                • 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
                                                  Ну так скажите пару слов :)
                                                  Хотя бы дайте ключевое слово ("замыкание"), чтобы начинающим читателям было куда копать :)
                                              • +1
                                                поразительно! статья об Обьектах в JS и ни одного слова " prototype ". *откашливаецо*
                                                • 0
                                                  за что я люблю хабру, так это за то, что кроме полезной статьи (такие бывают :)) в комментах пишут ооочень много полезного (иногда больше полезного чем в самой статье), так что товарищи, читаем комменты и мотаем на ус.
                                                  • +3
                                                    Я смотрю, http://sphere.habrahabr.ru/blog/28641.ht… прошла лесом.
                                                    • +1
                                                      вы б ее в коллективный блог добавили...
                                                    • 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
                                                                Спасибо, хорошая статья!

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