Оглавление

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

Создать новый объект можно с помощью встроенного класса object:

   var car = new Object();
   car.model = "ВАЗ-2109"; // Сохранили строку
   car.year = 2007; // Сохранили число
   car.getModel = function() { // Сохранили ссылку на функцию
      return this.model;
   };
   // Вывод значений
   window.alert(car.model); // "ВАЗ-2109"
   window.alert(car.year); // 2007
   window.alert(car.getModel()); // "ВАЗ-2109"


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

 

Создать объект можно также с помощью фигурных скобок:

   var car = {
      model: "ВАЗ-2109", // Сохранили строку
      year: 2007, // Сохранили число
      getModel: function() { // Сохранили ссылку на функцию
         return this.model;
      }
   };
   // Вывод значений
   window.alert(car.model); // "ВАЗ-2109"
   window.alert(car.year); // 2007
   window.alert(car.getModel()); // "ВАЗ-2109"


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

   var obj = {}; // Пустой объект

При создании объектов следует учитывать один очень важный момент. Например, нам необходимо определить два пустых объекта, которые в дальнейшем будут использоваться раздельно. Очень силен соблазн написать следующим образом:

   var obj1 = obj2 = {}; // Якобы определили два объекта

Проблема заключается в том, что в данном примере создается только один объект, а ссылка на него сохраняется в двух переменных. Таким образом, все изменения obj1 будут отражаться и на переменной obj2:

   var obj1 = obj2 = {}; // Якобы определили два объекта
   obj1.test = "Это значение свойства test объекта obj1";
   window.alert(obj2.test);
   // Выведет: Это значение свойства test объекта obj1


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

   var obj1 = {};
   var obj2 = {};
   obj1.test = "Это значение свойства test объекта obj1";
   window.alert(obj2.test); // Выведет: undefined


Если после ключевого слова new указана функция, то она становится конструктором объекта, которому можно передать начальные данные при инициализации. Внутри конструктора доступен указатель (this) на текущий объект:

   function Cars(m, y) { // Конструктор объекта
      this.model = m;
      this.year = y;
      this.getModel = function() {
         return this.model;
      }
   }
   // Создание экземпляра
   var car = new Cars("ВАЗ-2109", 2007);
   // Вывод значений
   window.alert(car.model); // "ВАЗ-2109"
   window.alert(car.year); // 2007
   window.alert(car.getModel()); // "ВАЗ-2109"


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

   function Cars() { }
   Cars.model = "ВАЗ-2109";
   Cars.year = 2007;
   Cars.getModel = function() {
      return Cars.model;
   };


Получить значения свойств и вызвать метод можно без создания экземпляра:

   window.alert(Cars.model); // "ВАЗ-2109"
   window.alert(Cars.year); // 2007
   window.alert(Cars.getModel()); // "ВАЗ-2109"


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

   window.alert(car["model"]); // "ВАЗ-2109"
   window.alert(car["year"]); // 2007
   window.alert(car["getModel"]()); // "ВАЗ-2109"


Обратите внимание на то, что название указывается в виде строки, которую можно изменить внутри программы динамически. Это обстоятельство позволяет обратиться к свойствам, названия которых заранее неизвестны. Выведем названия всех свойств и их значения с помощью цикла for...in:

   function Cars(m, y) { // Конструктор объекта
      this.model = m;
      this.year = y;
   }
   // Создание экземпляра
   var car = new Cars("ВАЗ-2109", 2007);
   // Вывод всех значений
   for (var P in car) {
      // Переменной P на каждой итерации присваивается
      // название свойства объекта
      window.alert(P + " = " + car[P]);
   }


Оператор in позволяет также проверить существование свойства (включая унаследованные) у объекта. Если свойство существует, то возвращается значение true:

   if ("model" in car) window.alert("Свойство определено");
   else window.alert("Нет");

 

Проверить    наличие    не    унаследованного    свойства    позволяет    метод hasOwnProperty(). В качестве значения указывается название свойства:

   if ("toString" in car) window.alert("Свойство определено");
   else window.alert("Нет");
   // Выведет: "Свойство определено"
   if (car.hasOwnProperty("toString"))
      window.alert("Свойство определено");
   else window.alert("Нет");
   // Выведет: "Нет", так как toString является унаследованным свойством
   if (car.hasOwnProperty("getModel"))
      window.alert("Свойство определено");
   else window.alert("Нет");
   // Выведет: "Свойство определено"

 

Если название метода указать в условии без круглых скобок, то это позволит проверить наличие метода:

   if (car.getModel) window.alert("Метод определен");
   else window.alert("Нет");


Обратите внимание на то, что проверять таким образом наличие свойства

нельзя, так как значение 0 будет интерпретировано как false.
С помощью оператора instanceof можно проверить принадлежность экземпляра какому-либо объекту:

   if ((typeof car == "object") && (car instanceof Cars))
      window.alert("Экземпляр car принадлежит объекту Cars");
   else window.alert("Нет");


Удалить свойство позволяет оператор delete:

   delete car.model;
Комментарии принадлежат их авторам. Мы не несем ответственности за их содержание.
Отправитель Нити