В этом блоге мы увидим, когда мы создаем объекты, что происходит за кулисами и насколько мощными и настраиваемыми являются свойства объекта.
Это следующие способы создания объектов в Javascript:
Создайте объект с литералом объекта,
'use strict' var cat = {name: 'blacky', color: 'black'} console.log(cat)
Вывод:
{name: "blacky", color: "black"}
Создайте объект с помощью функции-конструктора с ключевым словом new, и это позволит нам создать несколько экземпляров с той же структурой объекта, что и класс на языке со статической типизацией,
'use strict' function Cat() { this.name = "blacky"; this.color = "black"; } var cat = new Cat(); console.log(cat);
Вывод:
Cat {name: "blacky", color: "black"}
До сих пор мы видели два способа (литерал объекта и функция-конструктор с ключевым словом new) для создания объекта. На самом деле они являются синтаксическим сахаром для object.create . Мы могли бы создать такой же объект, используя object.create. Мы передаем Object.prototype, который станет прототипом вновь созданного объекта. Вы можете видеть, что мы создаем свойства имени и цвета. И для каждого мы присваиваем значение и устанавливаем перечисляемый, записываемый и настраиваемый. Все это происходит, когда мы создаем с использованием двух вышеуказанных методов.
'use strict' var cat = Object.create(Object.prototype, { name:{ value: 'blacky', enumerable: true, writable: true, configurable: true }, color:{ value: 'black', enumerable: true, writable: true, configurable: true } }) console.log(cat)
Вывод:
{name: "blacky", color: "black"}
ES6 предоставляет функциональность для создания объектов с использованием класса так же, как и в языке со статической типизацией. Опять же, это просто синтаксический сахар поверх существующей функциональности создания объектов. Таким образом, мы могли бы создать тот же объект, используя класс,
'use strict' class Cat { constructor(name, color) { this.name = name this.color = color } } var cat = new Cat('blacky', 'black') console.log(cat)
Вывод:
Cat {name: "blacky", color: "black"}
Итак, теперь мы увидим свойства объекта. Вы можете быть удивлены тем, что свойство — это больше, чем просто имя и значение. Каждое свойство имеет дескриптор свойства, и с его помощью мы можем видеть атрибуты свойства.
Для простоты мы используем здесь объектный литерал,
'use strict' var cat = { name: 'blacky', color: 'black'} console.log(Object.getOwnPropertyDescriptor(cat, 'name'))
Вывод:
{value: "blacky", writable: true, enumerable: true, configurable: true}
В выводе мы видим доступные для записи, перечисляемые и настраиваемые атрибуты, которые мы использовали ранее для создания объекта с помощью метода object.create. Так что же это?
Атрибут writable определяет, может ли значение свойства быть изменено по сравнению с его начальным значением. Мы можем сделать свойство name недоступным для записи, например,
'use strict' var cat = { name: 'blacky', color: 'black'} Object.defineProperty(cat, 'name', {writable: false}) console.log(Object.getOwnPropertyDescriptor(cat, 'name')) cat.name = 'jacky'
Вывод:
{value: "blacky", writable: false, enumerable: true, configurable: true} Uncaught TypeError: Cannot assign to read only property 'name' of object '#<Object>' at <anonymous>:7:10
На приведенном выше мы видим, что мы получили ошибку. Потому что мы сделали свойство name недоступным для записи. Есть еще одна вещь, которую нужно посмотреть,
'use strict' var cat = { name: {first: 'bla', last: 'cky'}, color: 'black'} Object.defineProperty(cat, 'name', {writable: false}) console.log(Object.getOwnPropertyDescriptor(cat, 'name')) cat.name.first = 'jacky' console.log(cat.name)
Вывод:
{value: {…}, writable: false, enumerable: true, configurable: true} {first: "jacky", last: "cky"}
В приведенном выше примере мы не видим никакой ошибки, хотя свойство name доступно только для чтения. имя — это просто указатель, указывающий на объект, содержащий первое и последнее свойство. и это предотвращает изменение этого указателя. Но на самом деле вы можете запретить изменение объекта с помощью object.freeze и давайте посмотрим, как это сделать.
'use strict' var cat = { name: {first: 'bla', last: 'cky'}, color: 'black'} Object.defineProperty(cat, 'name', {writable: false}) console.log(Object.getOwnPropertyDescriptor(cat, 'name')) Object.freeze(cat.name) cat.name.first = 'jacky' console.log(cat.name)
Вывод:
{value: {…}, writable: false, enumerable: true, configurable: true} Uncaught TypeError: Cannot assign to read only property 'first' of object '#<Object>' at <anonymous>:8:16
Теперь мы видим, что получили ошибку, означающую, что весь объект name доступен только для чтения.
Теперь мы рассмотрим атрибут enumerable на примере,
'use strict' var cat = { name: 'blacky', color: 'black'} for(var key in cat) { console.log(key) }
Вывод:
name color
Мы можем перебирать свойства объекта cat. По умолчанию свойство объекта является перечисляемым. Мы можем это изменить,
'use strict' var cat = { name: 'blacky', color: 'black'} Object.defineProperty(cat, 'name', {enumerable: false}) for(var key in cat) { console.log(key) }
Вывод:
color
В выводе мы видим только ключ свойства color. Изменение enumerable на false для name приводит к тому, что ключ не отображается в ключах объекта.
Атрибут configurable блокирует свойство, чтобы предотвратить изменение определенных атрибутов, а также предотвращает удаление свойства в объекте. Мы увидим на примере,
'use strict' var cat = { name: 'blacky', color: 'black'} Object.defineProperty(cat, 'name', {configurable: false}) Object.defineProperty(cat, 'name', {enumerable: false})
Вывод:
Uncaught TypeError: Cannot redefine property: name at Function.defineProperty (<anonymous>) at <anonymous>:6:8
У нас есть ошибка в этом случае. После установки для параметра configurable значения false мы не можем изменить определенные конфигурации свойства name. Теперь мы увидим, что он также предотвращает удаление свойства и выдает ошибку,
'use strict' var cat = { name: 'blacky', color: 'black'} Object.defineProperty(cat, 'name', {configurable: false}) delete cat.name
Вывод:
Uncaught TypeError: Cannot delete property 'name' of #<Object> at <anonymous>:6:1
Но теперь мы увидим, что мы меняем атрибут writable без каких-либо ошибок,
'use strict' var cat = { name: 'blacky', color: 'black'} Object.defineProperty(cat, 'name', {configurable: false}) Object.defineProperty(cat, 'name', {writable: false})
Здесь мы не получили никакой ошибки в выводе.
Вывод
Мы узнали об объекте Javascript и свойствах его свойств, а также о том, насколько они настраиваются.
Надеюсь, вам понравился этот блог...