Глубокое погружение в объекты Javascript

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

Javascript — это объектно-ориентированный язык сценариев, и понимание природы объекта особенно важно для контроля над основным языком.

с введением классов JavaScript, представленных в ECMAScript 2015, определение объектов стало абстрактным. тем не менее, поддержка объявления класса - это просто синтаксический сахар, а javascript по-прежнему основан на прототипе и не добавляет никаких функций в существующую модель. Поэтому понимание того, что абстракция класса выполняет под капотом, по-прежнему ценно.

Перейдите по следующей ссылке, если вы хотите глубже понять Определение класса JavaScript ECMAScript 2015.

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

Введение

Из-за динамической природы javascript создание объекта так же просто, как код ниже.

var myObject = {};

приведенный выше код создает объект с именем myObject, который расширяет базовый прототип класса Объект без свойств. объект прототипа выходит за рамки этой статьи, но вы можете обратиться к этой ссылке, если хотите понять больше.

Теперь, если вы хотите создать объект со свойствами, вы можете изменить приведенный выше код, как показано ниже.

var myObject = {
       firstProperty: '',
       secondProperty: 100,
       thirdProperty: []
}

Или добавить свойства после создания объекта

var myObject = {};
myObject.firstProperty = '';
myObject.secondPropery = 100;
myObject.thirdProperty = [];

Хотя приведенные выше инструкции являются допустимыми способами создания объекта и инициализации его свойств, они скрывают всю конфигурацию, которая происходит в фоновом режиме.

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

Javascript-объекты 101

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

В javascript объекты можно рассматривать как набор свойств.

Свойства объекта Javascript

Объекты Javascript имеют два свойства.

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

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

— Общие атрибуты

  • Enumerable(boolean: false) — логическое значение, указывающее, доступно ли свойство через итераторы, такие как for…in loops, операторы расширения, Object.keys(). если оставить его неопределенным, он примет значение по умолчанию false.
  • Configurable(boolean: false) — логическое значение, указывающее, можно ли удалить свойство с помощью оператора delete. он примет значение по умолчанию false, если его не указать. При попытке удалить свойство в sloppy mode операция будет проигнорирована, а в strict mode будет выдана ошибка.

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

— Атрибуты свойства данных

  • Value([string|object|number|Array|null]: undefined) —содержит фактическое значение свойства. это может быть любой допустимый тип данных javascript. когда мы устанавливаем значение с помощью этого свойства, это то же самое, что присваивать его напрямую, как мы видели ранее. если оставить его неопределенным, он примет значение по умолчанию undefined.
  • Доступно для записи (boolean: false) — используется для указания, может ли свойство быть присвоено другое значение после момента создания. если оставить его неопределенным, оно примет значение по умолчанию false, что означает, что свойство становится read-only.

Если мы попытаемся переназначить новое значение для свойства с доступным для записи значением, установленным на false в sloppy mode, назначение будет проигнорировано, а на strict mode произойдет ошибка.

— Атрибуты свойств средства доступа

  • get (Function: undefined) — вызывается всякий раз, когда мы пытаемся получить значение свойства, связанного с этим атрибутом, в виде функции, не принимающей аргументов.
  • set(Function: undefined) — используется для изменения значения свойства. это функция, которая вызывается с одним аргументом, содержащим присвоенное значение, и выполняется при каждой попытке изменить указанное свойство.

Как мы видим, существует множество свойств, которые мы можем использовать для настройки свойств объектов в нашем приложении.

Взаимная эксклюзивность между конфигурациями

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

Значение и запись по сравнению с установить и получить утверждение

  • вы можете установить данные writable & valueproperties, а также определить набор и получить доступ, поскольку они создают конфликты.

в этих случаях выдается ошибка, похожая на oojs.html:34 Uncaught TypeError: Invalid property descriptor. Cannot both specify accessors and a value or writable attribute, #<Object>.

Но как мы на самом деле устанавливаем эти значения, как вы сказали? хорошо, что мы являемся одной из предопределенных функций для глобального Объекта Object.definePropertiy и Object.defineProperties, вступающих в игру.

Знакомство с Object.defineProperty()

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

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

Object.definePropertyвзять 3 аргумента.

Object.defineProperty(obj: Object, key: strinng, config: Object)

  • Объект — первый аргумент принимает объект, на который мы хотим настроить.
  • ключ — строковое значение, указывающее свойство, атрибуты которого мы хотим изменить. если указанный ключ не существует, object.defineProperties создаст ключ.
  • config — последний аргумент используется для определения значений атрибутов свойства. мы можем передать пустой объект для этого значения, и в этом случае значения атрибута по умолчанию.
Object.defineProperty(Object, 'key: String', {
                           configurable: Boolean,
                           writable: Boolean,
                           enumerable: Boolean,
                           value: String|Number|Array|Object,
                           get: Function,
                           set: Function
                      });

— его родственный элемент Object.defineProperties()принимает 2 аргумента

Object.defineProperty(obj: Object, config: Object)

  • Объект — объект, который вы хотите настроить.
  • config — объект конфигурации.
Object.defineProperties(Object, {
                 'propertyName': string    {
                           configurable: Boolean,
                           writable: Boolean,
                           enumerable: Boolean,
                           value: String|Number|Array|Object,
                           get: Function,
                           set: Function
                      },
                 'propertyName': string     {
                           configurable: Boolean,
                           writable: Boolean,
                           enumerable: Boolean,
                           value: String|Number|Array|Object,
                           get: Function,
                           set: Function
                      },{}...});

Настройка свойств объекта с помощью Object.create()

событие, хотя object.defineProperty и Object.defineProperties являются выделенными функциями для установки свойств объекта, есть еще один способ, который мы можем использовать для установки свойств объектов, то есть использование второго аргумента функции Object.create(), которая принимает объект конфигурации свойства.

var myObject = Object.create({}, {
                 'propertyName': string    {
                           configurable: Boolean,
                           writable: Boolean,
                           enumerable: Boolean,
                           value: String|Number|Array|Object,
                           get: Function,
                           set: Function
                      },
                 'propertyName': string     {
                           configurable: Boolean,
                           writable: Boolean,
                           enumerable: Boolean,
                           value: String|Number|Array|Object,
                           get: Function,
                           set: Function
                      }...} )

Примеры

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

1 объект со значением по умолчанию

var myObject = {};
Object.defineProperty(myObject, 'firstProperty', {
                        configurable: false, 
                        writable: true,
                        value: 200,         //default value
                        enumerable: false,
                        set(val) {
                               this.first = val;
                        },
                        get() {
                               return this.first;
                        }
                     });

> console.log(myObject);
> 200 

2 Свойство только для чтения — Soppy-mode

var myObject = {};
Object.defineProperty(myObject, 'firstProperty', {
                                       configurable: false,
                                       writable: false,
                                       value: 200,
                                       enumerable: false
                      });
 myObject.firstProperty = 100; // will not affect the value
console.log(myObject.firstProperty);
> 200  // same as defined inside object.defineProperty()

3 Свойство только для чтения — строгий режим

'use strict'; // strict mode
var myObject = {};
Object.defineProperty(myObject, 'firstProperty', {
                                       configurable: false,
                                       writable: false,
                                       value: 200,
                                       enumerable: false
                      });
myObject.firstProperty = 100; // will throw error
console.log(myObject.firstProperty);
> Uncaught TypeError: Cannot assign to read only property 'firstProperty' of object '#<Object>'

4. Установка нескольких значений с помощью Object.defineProperties

var myObject = {};
Object.defineProperties(myObject, {
                    firstProperty: {
                                     configurable: false,
                                     writable: true,
                                     value: 200,
                                     enumerable: false
                                    },
                   secondProperty: {
                                     configurable: false,
                                     writable: true,
                                     value: 100,
                                     enumerable: false
                                   }
                  });

> console.log(myObject.firstProperty);
> 200
> console.log(myObject.secondProperty);
> 100

5 Скрыть свойство от итераторов

var myObject = {};
Object.defineProperties(myObject, {
                       firstProperty: {
                           configurable: false,
                           writable: true,
                           value: 200,
                           enumerable: true
                       },
                       secondProperty: {
                            configurable: false,
                            writable: true,
                            value: 100,
                       // hidden from itterators  
                            enumerable: false 
                           }
                         });
     for (const key in myObject) {
              console.log(key);
      }
> firstProperty

6 Ограничить удаление — небрежный режим

var myObject = {};
Object.defineProperty(myObject, 'firstProperty', 
                                    {
                                 // disable delete
                                      configurable: false,
                                      writable: true,
                                      value: 200,
                                      enumerable: true
                      });
// does not have any effect
delete myObject.firstProperty; 
console.log(myObject.firstProperty);
> 200 // value still available

7 Ограничить удаление — небрежный режим

'use strict';
var myObject = {};
Object.defineProperty(myObject, 'firstProperty', 
                                    {
                                 // disable delete
                                      configurable: false,
                                      writable: true,
                                      value: 200,
                                      enumerable: true
                      });
// will throw error since firstProperty is not configurable
delete myObject.firstProperty;
console.log(myObject.firstProperty);
> Uncaught TypeError: Cannot delete property 'firstProperty' of #<Object>

8 Определить метод доступа к свойству

var myObject = {};
Object.defineProperty(myObject, 'firstProperty', {
                                      
                               configurable: false,
                               enumerable: true,
                               get() {  return this.first;},
                               set(val) {
                            // change value to uppercase
                           return (this.first = val.toUpperCase());
                                });
myObject.firstProperty = 'Mikael Araya';
console.log(myObject.firstProperty);
> MIKAEL ARAYA

9 Определите свойство объекта с помощью Object.create

var myObject = Object.create({}, {
                    firstProperty: {
                                     configurable: false,
                                     writable: true,
                                     value: 200,
                                     enumerable: false
                                    },
                   secondProperty: {
                                     configurable: false,
                                     writable: true,
                                     value: 100,
                                     enumerable: false
                                   }
                  });
console.log(myObject.firstProperty);
> 200
console.log(myObject.secondProperty);
> 100

Вывод

Несмотря на то, что существует множество библиотек и фреймворков, абстрагирующих движок подчеркивания javascript, понимание того, как реализованы некоторые аспекты языка, необходимо для полного контроля над инструментом.

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

Справочник