04. Object Properties

Access to properties

Общий синтаксис:

const object = {
  foo: "bar",
  age: 42,
  baz: { myProp: 12 }
};

object.foo; // "bar"
object["age"]; // 42
object.foo = "baz";

В JS можно обратиться к любому свойству объекта, даже если его нет. Ошибки не будет. Но если свойство не существует, то вернется undefined.

Попытка присвоить значение свойству p объекта o потерпит неудачу в следующих случаях:

  • Объект o имеет собственное свойство p, доступное только для чтения: нельзя изменить значение свойства, доступного только для чтения.

  • Объект o имеет унаследованное свойство p, доступное только для чтения: унаследованные свойства, доступные только для чтения, невозможно переопределить собственными свойствами с теми же именами.

  • Объект o не имеет собственного свойства p; объект o не наследует свойство p с методами доступа и атрибут extensible объекта o имеет значение false.

Safe property access

Для безопасного доступа к полям объекта можно использовать операторы || и && и ??. Разница между ними в том, что || и && выполняют более общую проверку на truthy/falsy, тогда как ?? только на null или undefined.

Optional chaining в ES2020 позволяет обращаться к вложенным полям объекта при условии, что предыдущие поля в пути определены:

Property access in the spec

The operator for getting and setting properties uses the internal operation ToPropertyKey(), which works as follows:

  • Convert the operand to a primitive via ToPrimitive() with the preferred type String:

    • A primitive value is returned as it is.

    • Otherwise, the operand is an object. If it has a method [@@toPrimitive](), that method is used to convert it to a primitive value. Symbols have such a method, which returns the wrapped symbol.

    • Otherwise, the operand is converted to a primitive via toString() – if it returns a primitive value. Otherwise, valueOf() is used – if it returns a primitive value. The preferred type String determines that toString() is called first, valueOf() second.

    • Otherwise, a TypeError is thrown.

  • If the result of the conversion is a symbol, return it.

  • Otherwise, coerce the result to string via ToString().

Operator delete

Единственным способом удалить пару ключ-значение из объекта является оператор delete. Если присвоить ключу значение undefined, то мы удалим только значение, ключ останется в объекте. Если не использовать delete, то ключ будет встречаться при перечислении ключей объекта.

  • Оператор delete удаляет только собственные свойства и не удаляет унаследованные.

  • Нельзя удалить non-configurable свойство.

  • Чтобы удалить унаследованное свойство, необходимо удалять его в объекте-прототипе, в котором оно определено. Такая операция затронет все объекты, наследующие этот прототип.

Оператор delete возвращает false если удаляемое свойство является свойством объекта, но не может быть удалено. В остальных случаях оператор возвращает false.

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

An algorithm for delete is specified roughly like this:

  • If operand is not a reference, return true

  • If object has no direct property with such name, return true (where, as we now know, object can be Activation object or Global object)

  • If property exists but has DontDelete, return false

    Otherwise, remove property and return true

Check property existence

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

Operator in

Оператор in требует, чтобы в левом операнде ему было передано имя свойства (в виде строки) и объект в правом операнде. Он возвращает true, если объект имеет собственное или унаследованное свойство с этим именем. В противном случае возвращает undefined.

obj.hasOwnProperty()

Метод hasOwnProperty() объекта проверяет, имеет ли объект собственное свойство с указанным именем. Для наследуемых свойств он возвращает false.

obj.propertyIsEnumerable()

Метод propertyIsEnumerable() накладывает дополнительные ограничения по сравнению с hasOwnProperty(). Он возвращает true, только если указанное свойство является собственным свойством, атрибут enumerable которого имеет значение true.

Last updated

Was this helpful?