Spec-Zone.ru › JavaScript

Объект

Базовая поддержка Широко доступно

Эта функция хорошо зарекомендовала себя и работает на многих устройствах и версиях браузеров. Она доступна в браузерах с июля 2015 года.

Тип Object представляет собой один из типов данных JavaScript. Он используется для хранения различных коллекций с ключами и более сложных сущностей. Объекты могут быть созданы с помощью конструктора Object() или с помощью инициализатора объектов / синтаксиса литерала.

Описание

Почти все объекты в JavaScript являются экземплярами Object; типичный объект наследует свойства (включая методы) от Object.prototype, хотя эти свойства могут быть скрыты (также известны как переопределены). Единственные объекты, которые не наследуют от Object.prototype, — это объекты с прототипом null или унаследованные от других объектов с прототипом null.

Изменения в объекте Object.prototype видны всем объектам через цепочку прототипов, если только свойства и методы, подверженные этим изменениям, не переопределены дальше по цепочке прототипов. Это обеспечивает очень мощный, хотя и потенциально опасный механизм для переопределения или расширения поведения объектов. Для повышения безопасности Object.prototype является единственным объектом в основном языке JavaScript, который имеет неизменяемый прототип — прототип Object.prototype всегда является null и не может быть изменен.

Свойства прототипа объекта

Следует избегать прямого вызова каких-либо методов Object.prototype из экземпляра, особенно тех, которые не предназначены для полиморфизма (то есть, только их первоначальное поведение имеет смысл, и ни один производный объект не может значимо его переопределить). Все объекты, производные от Object.prototype, могут определять собственное свойство с тем же именем, но с совершенно иной семантикой, чем вы ожидаете. Кроме того, эти свойства не наследуются объектами с прототипом null. Все современные утилиты JavaScript для работы с объектами являются статическими. Более конкретно:

  • valueOf(), toString() и toLocaleString() существуют для полиморфизма, и вы можете ожидать, что объект определит свою собственную реализацию с разумным поведением, поэтому вы можете вызывать их как методы экземпляра. Однако valueOf() и toString() обычно вызываются неявно через приведение типов, и вам не нужно вызывать их самостоятельно в своем коде.
  • __defineGetter__(), __defineSetter__(), __lookupGetter__() и __lookupSetter__() устарели и не должны использоваться. Вместо них используйте статические альтернативы Object.defineProperty() и Object.getOwnPropertyDescriptor().
  • Свойство __proto__ устарело и не должно использоваться. Альтернативные статические методы Object.getPrototypeOf() и Object.setPrototypeOf().
  • Методы propertyIsEnumerable() и hasOwnProperty() могут быть заменены статическими методами Object.getOwnPropertyDescriptor() и Object.hasOwn() соответственно.
  • Метод isPrototypeOf() обычно может быть заменен instanceof, если вы проверяете свойство prototype конструктора.

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

const obj = {
  foo: 1,
  // You should not define such a method on your own object,
  // but you may not be able to prevent it from happening if
  // you are receiving the object from external input
  propertyIsEnumerable() {
    return false;
  },
};

obj.propertyIsEnumerable("foo"); // false; unexpected result
Object.prototype.propertyIsEnumerable.call(obj, "foo"); // true; expected result

Удаление свойства из объекта

В самом объекте нет метода для удаления его собственных свойств (например, Map.prototype.delete()). Для этого необходимо использовать оператор delete.

Объекты с null-прототипом

Почти все объекты в JavaScript в конечном итоге наследуют от Object.prototype (см. наследование и цепочка прототипов). Однако вы можете создавать объекты с прототипом null, используя Object.create(null) или синтаксис инициализатора объектов с __proto__: null (примечание: ключ __proto__ в литералах объектов отличается от устаревшего свойства Object.prototype.__proto__). Вы также можете изменить прототип существующего объекта на null, вызвав Object.setPrototypeOf(obj, null).

const obj = Object.create(null);
const obj2 = { __proto__: null };

Объект с прототипом null может вести себя неожиданно, поскольку он не наследует никаких методов объектов от Object.prototype. Это особенно актуально при отладке, поскольку общие утилиты для преобразования/определения свойств объектов могут вызывать ошибки или терять информацию (особенно при использовании бесшумных ловушек ошибок, игнорирующих ошибки).

Например, отсутствие Object.prototype.toString() часто делает отладку невозможной:

const normalObj = {}; // create a normal object
const nullProtoObj = Object.create(null); // create an object with "null" prototype

console.log(`normalObj is: ${normalObj}`); // shows "normalObj is: [object Object]"
console.log(`nullProtoObj is: ${nullProtoObj}`); // throws error: Cannot convert object to primitive value

alert(normalObj); // shows [object Object]
alert(nullProtoObj); // throws error: Cannot convert object to primitive value

Другие методы также будут выдавать ошибки.

normalObj.valueOf(); // shows {}
nullProtoObj.valueOf(); // throws error: nullProtoObj.valueOf is not a function

normalObj.hasOwnProperty("p"); // shows "true"
nullProtoObj.hasOwnProperty("p"); // throws error: nullProtoObj.hasOwnProperty is not a function

normalObj.constructor; // shows "Object() { [native code] }"
nullProtoObj.constructor; // shows "undefined"

Мы можем добавить метод toString обратно в объект с null-прототипом, назначив его:

nullProtoObj.toString = Object.prototype.toString; // since new object lacks toString, add the original generic one back

console.log(nullProtoObj.toString()); // shows "[object Object]"
console.log(`nullProtoObj is: ${nullProtoObj}`); // shows "nullProtoObj is: [object Object]"

В отличие от обычных объектов, у которых toString() находится в прототипе объекта, метод toString() здесь является собственным свойством nullProtoObj. Это потому, что nullProtoObj не имеет (null) прототипа.

Вы также можете вернуть объект с null-прототипом обратно в обычный объект, используя Object.setPrototypeOf(nullProtoObj, Object.prototype).

На практике объекты с прототипом null обычно используются как дешевая замена картам. Наличие свойств Object.prototype вызовет некоторые ошибки:

const ages = { alice: 18, bob: 27 };

function hasPerson(name) {
  return name in ages;
}

function getAge(name) {
  return ages[name];
}

hasPerson("hasOwnProperty"); // true
getAge("toString"); // [Function: toString]

Использование объекта с null-прототипом устраняет эту опасность, не внося слишком большой сложности в функции hasPerson и getAge:

const ages = Object.create(null, {
  alice: { value: 18, enumerable: true },
  bob: { value: 27, enumerable: true },
});

hasPerson("hasOwnProperty"); // false
getAge("toString"); // undefined

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

Ненаследование вашего объекта от Object.prototype также предотвращает атаки на загрязнение прототипов. Если вредоносный скрипт добавляет свойство к Object.prototype, оно будет доступно каждому объекту в вашей программе, кроме объектов с null-прототипом.

const user = {};

// A malicious script:
Object.prototype.authenticated = true;

// Unexpectedly allowing unauthenticated user to pass through
if (user.authenticated) {
  // access confidential data
}

JavaScript также имеет встроенные API, которые возвращают объекты с прототипом null, особенно те, которые используют объекты в качестве временных коллекций пар ключ-значение. Например:

  • Возвращаемое значение Object.groupBy()
  • Свойства groups и indices.groups результата RegExp.prototype.exec()
  • Array.prototype[Symbol.unscopables] (все объекты [Symbol.unscopables] должны иметь прототип null)
  • import.meta
  • Объекты пространства имен модулей, полученные через import * as ns from "module"; или import()

Термин «объект с прототипом null» часто также включает любой объект без Object.prototype в своей цепочке прототипов. Такие объекты могут быть созданы с помощью extends null при использовании классов.

Приведение объекта

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

  • Объекты возвращаются как есть.
  • undefined и null вызывают TypeError.
  • Примитивы Number, String, Boolean, Symbol, BigInt оборачиваются в соответствующие объектные обертки.

Существует два способа достижения почти такого же эффекта в JavaScript.

  • Object.prototype.valueOf(): Object.prototype.valueOf.call(x) выполняет шаги приведения к объекту, описанные выше, для преобразования x.
  • Функция Object(): Object(x) использует тот же алгоритм для преобразования x, за исключением того, что undefined и null не вызывают TypeError, а возвращают обычный объект.

Места, где используется приведение объектов, включают:

  • Параметр object циклов for...in.
  • Значение this методов Array.
  • Параметры методов Object, таких как Object.keys().
  • Автоматическая упаковка при доступе к свойству примитивного значения, поскольку примитивы не имеют свойств.
  • Значение this при вызове нестрогой функции. Примитивы упаковываются, в то время как null и undefined заменяются глобальным объектом.

В отличие от преобразования в примитивы, сам процесс приведения объектов никак не наблюдается, поскольку он не вызывает пользовательский код, такой как методы toString или valueOf.

Конструктор

Object()
Преобразует входные данные в объект.

Статические методы

Object.assign()
Копирует значения всех перечисляемых собственных свойств из одного или нескольких исходных объектов в целевой объект.
Object.create()
Создает новый объект с указанным объектом прототипа и свойствами.
Object.defineProperties()
Добавляет именованные свойства, описанные в заданных дескрипторах, к объекту.
Object.defineProperty()
Добавляет именованное свойство, описанное в заданном дескрипторе, к объекту.
Object.entries()
Возвращает массив, содержащий все пары [key, value] объекта.
Object.freeze()
Замораживает объект. Другой код не может удалять или изменять его свойства.
Object.fromEntries()
Возвращает новый объект из итерируемого объекта пар [key, value]. (Это обратное действие Object.entries).
Object.getOwnPropertyDescriptor()
Возвращает дескриптор свойства для именованного свойства в объекте.
Object.getOwnPropertyDescriptors()
Возвращает объект, содержащий все дескрипторы собственных свойств объекта.
Object.getOwnPropertyNames()
Возвращает массив, содержащий имена всех собственных перечисляемых и неперечисляемых свойств объекта.
Object.getOwnPropertySymbols()
Возвращает массив всех символьных свойств, найденных непосредственно в указанном объекте.
Object.getPrototypeOf()
Возвращает прототип (внутреннее свойство [[Prototype]]) указанного объекта.
Object.groupBy()
Группирует элементы заданного итерируемого объекта в соответствии со строковыми значениями, возвращаемыми предоставленной функцией обратного вызова. Возвращаемый объект имеет отдельные свойства для каждой группы, содержащие массивы с элементами в группе.
Object.hasOwn()
Возвращает true, если указанный объект имеет указанное свойство как свое собственное свойство, или false, если свойство унаследовано или отсутствует.
Object.is()
Сравнивает, являются ли два значения одним и тем же значением. Приравнивает все значения NaN (что отличается как от IsLooselyEqual, используемого ==, так и от IsStrictlyEqual, используемого ===).
Object.isExtensible()
Определяет, разрешено ли расширение объекта.
Object.isFrozen()
Определяет, был ли объект заморожен.
Object.isSealed()
Определяет, является ли объект запечатанным.
Object.keys()
Возвращает массив, содержащий имена всех собственных перечисляемых строковых свойств объекта.
Object.preventExtensions()
Предотвращает любые расширения объекта.
Object.seal()
Запрещает другому коду удалять свойства объекта.
Object.setPrototypeOf()
Устанавливает прототип объекта (его внутреннее свойство [[Prototype]]).
Object.values()
Возвращает массив, содержащий значения, соответствующие всем собственным перечисляемым строковым свойствам указанного объекта.

Свойства экземпляра

Эти свойства определены на Object.prototype и разделяются всеми экземплярами Object.

Object.prototype.__proto__ Устарело
Указывает на объект, который использовался в качестве прототипа при создании экземпляра объекта.
Object.prototype.constructor
Конструктор, создавший экземпляр объекта. Для обычных экземпляров Object начальное значение — конструктор Object. Экземпляры других конструкторов наследуют свойство constructor от соответствующего объекта Constructor.prototype.

Методы экземпляра

Object.prototype.__defineGetter__() Устарело
Связывает функцию со свойством, которая при доступе к нему выполняет эту функцию и возвращает ее результат.
Object.prototype.__defineSetter__() Устарело
Связывает функцию со свойством, которая при установке выполняет эту функцию, модифицирующую свойство.
Object.prototype.__lookupGetter__() Устарело
Возвращает функцию, связанную как геттер с указанным свойством.
Object.prototype.__lookupSetter__() Устарело
Возвращает функцию, связанную как сеттер с указанным свойством.
Object.prototype.hasOwnProperty()
Возвращает логическое значение, указывающее, содержит ли объект указанное свойство как собственное свойство объекта, а не унаследованное через цепочку прототипов.
Object.prototype.isPrototypeOf()
Возвращает логическое значение, указывающее, находится ли объект, для которого вызывается этот метод, в цепочке прототипов указанного объекта.
Object.prototype.propertyIsEnumerable()
Возвращает логическое значение, указывающее, является ли указанное свойство перечисляемым собственным свойством объекта.
Object.prototype.toLocaleString()
Вызывает toString().
Object.prototype.toString()
Возвращает строковое представление объекта.
Object.prototype.valueOf()
Возвращает примитивное значение указанного объекта.

Примеры

Создание пустых объектов

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

const o1 = new Object();
const o2 = new Object(undefined);
const o3 = new Object(null);

Использование конструктора Object() для преобразования примитивов в объект соответствующего типа

Вы можете использовать конструктор Object() для создания объектной обертки примитивного значения.

Следующие примеры создают переменные o1 и o2, которые являются объектами, хранящими значения Boolean и BigInt:

// Equivalent to const o1 = new Boolean(true)
const o1 = new Object(true);

// No equivalent because BigInt() can't be called as a constructor,
// and calling it as a regular function won't create an object
const o2 = new Object(1n);

Прототипы объектов

При изменении поведения существующих методов Object.prototype рассмотрите возможность внедрения кода путем оборачивания вашего расширения до или после существующей логики. Например, этот (непротестированный) код предварительно условно выполнит пользовательскую логику перед выполнением встроенной логики или расширения другого разработчика.

При модификации прототипов с помощью хуков передавайте this и аргументы (состояние вызова) текущему поведению, вызывая apply() для функции. Этот шаблон может использоваться для любого прототипа, такого как Node.prototype, Function.prototype и т. д.

const current = Object.prototype.valueOf;

// Since my property "-prop-value" is cross-cutting and isn't always
// on the same prototype chain, I want to modify Object.prototype:
Object.prototype.valueOf = function (...args) {
  if (Object.hasOwn(this, "-prop-value")) {
    return this["-prop-value"];
  }
  // It doesn't look like one of my objects, so let's fall back on
  // the default behavior by reproducing the current behavior as best we can.
  // The apply behaves like "super" in some other languages.
  // Even though valueOf() doesn't take arguments, some other hook may.
  return current.apply(this, args);
};

Внимание: Изменение свойства prototype любого встроенного конструктора считается плохой практикой и рискует будущей совместимостью.

Вы можете узнать больше о прототипах в Наследование и цепочка прототипов.

Спецификации

Спецификация
ECMAScript® 2027 Language Specification
# sec-object-objects

Совместимость с браузерами

Desktop Mobile Server
Chrome Edge Firefox Opera Safari Chrome Android Firefox for Android Opera Android Safari on iOS Samsung Internet WebView Android WebView on iOS Bun Deno Node.js
Object
1
12
1
3
1
18
4
10.1
1
1.0
1
1
1.0.0
1.0
0.10.0
Object
1
12
1
3
1
18
4
10.1
1
1.0
1
1
1.0.0
1.0
0.10.0
assign
45
12
34
32
9
45
34
32
9
5.0
45
9
1.0.0
1.0
4.0.0
constructor
1
12
1
4
1
18
4
10.1
1
1.0
4.4
1
1.0.0
1.0
0.10.0
create
5
12
4
11.6
5
18
4
12
5
1.0
4.4
5
1.0.0
1.0
0.10.0
defineGetter
1
12
1Начиная с Firefox 48, этот метод больше нельзя вызывать в глобальной области без объекта. В противном случае будет выброшено TypeError. Ранее в этих случаях автоматически использовался глобальный объект, но теперь это не так.
9.5
3
18
4
10.1
1
1.0
4.4
1
1.0.0
1.0
0.10.0
defineProperties
5
12
4
11.6
5
18
4
12
5
1.0
4.4
5
1.0.0
1.0
0.10.0
defineProperty
5
12
4
11.6
5.1Также поддерживается в Safari 5, но не на DOM-объектах.
18
4
12
6Также поддерживается в Safari для iOS 4.2, но не на DOM-объектах.
1.0
4.4
6Также поддерживается в Safari для iOS 4.2, но не на DOM-объектах.
1.0.0
1.0
0.10.0
defineSetter
1
12
1Начиная с Firefox 48, этот метод больше нельзя вызывать в глобальной области без объекта. В противном случае будет выброшено TypeError. Ранее в этих случаях автоматически использовался глобальный объект, но теперь это не так.
9.5
3
18
4
10.1
1
1.0
4.4
1
1.0.0
1.0
0.10.0
entries
54
14
47
41
10.1
54
47
41
10.3
6.0
54
10.3
1.0.0
1.0
7.0.0
freeze
6
12
4
12
5.1
18
4
12
5
1.0
4.4
5
1.0.0
1.0
0.10.0
fromEntries
73
79
63
60
12.1
73
63
52
12.2
11.0
73
12.2
1.0.0
1.0
12.0.0
getOwnPropertyDescriptor
5
12
4
12
5
18
4
12
5
1.0
4.4
5
1.0.0
1.0
0.10.0
getOwnPropertyDescriptors
54
15
50
41
10
54
50
41
10
6.0
54
10
1.0.0
1.0
7.0.0
getOwnPropertyNames
5
12
4
12
5
18
4
12
5
1.0
4.4
5
1.0.0
1.0
0.10.0
getOwnPropertySymbols
38
12
36
25
9
38
36
25
9
3.0
38
9
1.0.0
1.0
0.12.0
getPrototypeOf
5
12
3.5
12.1
5
18
4
12.1
5
1.0
4.4
5
1.0.0
1.0
0.10.0
groupBy
117
117
119
103
17.4
16.4–17.4
117
119
78
17.4
16.4–17.4
24.0
117
17.4
16.4–17.4
1.0.19
1.37
21.0.0
hasOwn
93
93
92
79
15.4
93
92
66
15.4
17.0
93
15.4
1.0.0
1.13
16.9.0
hasOwnProperty
1
12
1
5
3
18
4
10.1
1
1.0
1
1
1.0.0
1.0
0.10.0
is
19
12
22
15
9
25
22
14
9
1.5
4.4
9
1.0.0
1.0
0.10.0
isExtensible
6
12
4
12
5.1
18
4
12
5
1.0
4.4
5
1.0.0
1.0
0.10.0
isFrozen
6
12
4
12
5.1
18
4
12
5
1.0
4.4
5
1.0.0
1.0
0.10.0
isPrototypeOf
1
12
1
4
3
18
4
10.1
1
1.0
1
1
1.0.0
1.0
0.10.0
isSealed
6
12
4
12
5.1
18
4
12
5
1.0
4.4
5
1.0.0
1.0
0.10.0
keys
5
12
4
12
5
18
4
12
5
1.0
4.4
5
1.0.0
1.0
0.10.0
lookupGetter
1
12
1
9.5
3
18
4
10.1
1
1.0
4.4
1
1.0.0
1.0
0.10.0
lookupSetter
1
12
1
9.5
3
18
4
10.1
1
1.0
4.4
1
1.0.0
1.0
0.10.0
preventExtensions
6
12
4
12
5.1
18
4
12
5
1.0
4.4
5
1.0.0
1.0
0.10.0
propertyIsEnumerable
1
12
1
4
3
18
4
10.1
1
1.0
1
1
1.0.0
1.0
0.10.0
proto
1
12
1
10.5
3
18
4
11
1
1.0
4.4
1
1.0.0
2.9
1.39
0.10.0
seal
6
12
4
12
5.1
18
4
12
5
1.0
4.4
5
1.0.0
1.0
0.10.0
setPrototypeOf
34
12
31
21
9
34
31
21
9
2.0
37
9
1.0.0
1.0
0.12.0
toLocaleString
1
12
1
4
1
18
4
10.1
1
1.0
1
1
1.0.0
1.0
0.10.0
toString
1
12
1
3
1
18
4
10.1
1
1.0
1
1
1.0.0
1.0
0.10.0
valueOf
1
12
1
3
1
18
4
10.1
1
1.0
1
1
1.0.0
1.0
0.10.0
values
54
14
47
41
10.1
54
47
41
10.3
6.0
54
10.3
1.0.0
1.0
7.0.0

См. также

  • Инициализатор объектов
  • Атака загрязнения прототипа

© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API