Object.create()
Метод Object.create() создаёт новый объект с указанным прототипом и свойствами.
Синтаксис
Object.create(proto[, propertiesObject])
Параметры
Объект, который станет прототипом вновь созданного объекта.
Необязательный параметр. Если указан и не равен undefined , должен быть объектом, чьи собственные перечисляемые свойства (то есть такие, которые определены на самом объекте, а не унаследованы по цепочке прототипов) указывают дескрипторы свойств, добавляемых в новый объект. Имена добавляемых свойств совпадают с именами свойств в этом объекте. Эти свойства соответствуют второму аргументу метода Object.defineProperties() .
Возвращаемые значения
Новый объект с заданным прототипом и свойствами
Выбрасываемые исключения
Выбрасывает исключение TypeError , если параметр proto не является null или объектом (исключение составляют объекты-обёртки примитивных типов).
Примеры
Пример: классическое наследование с Object.create()
Ниже показан пример использования Object.create() для имитации классического наследования. Это пример одиночного наследования, поскольку только его поддерживает JavaScript.
// Shape — суперкласс function Shape() this.x = 0; this.y = 0; > // метод суперкласса Shape.prototype.move = function (x, y) this.x += x; this.y += y; console.info("Фигура переместилась."); >; // Rectangle — подкласс function Rectangle() Shape.call(this); // вызываем конструктор суперкласса > // подкласс расширяет суперкласс Rectangle.prototype = Object.create(Shape.prototype); Rectangle.prototype.constructor = Rectangle; var rect = new Rectangle(); console.log( "Является ли rect экземпляром Rectangle? " + (rect instanceof Rectangle), ); // true console.log("Является ли rect экземпляром Shape? " + (rect instanceof Shape)); // true rect.move(1, 1); // выведет 'Фигура переместилась.'
Если вы хотите наследоваться от нескольких объектов, то это возможно сделать при помощи примесей.
function MyClass() SuperClass.call(this); OtherSuperClass.call(this); > MyClass.prototype = Object.create(SuperClass.prototype); // наследование mixin(MyClass.prototype, OtherSuperClass.prototype); // примешивание MyClass.prototype.myMethod = function () // что-то делаем >;
Функция примешивания должна копировать функции из прототипа суперкласса в прототип подкласса, она должна предоставляться пользователем. Примером примеси может служить функция jQuery.extend().
Пример: использование аргумента propertiesObject с Object.create()
var o; // создаём объект с нулевым прототипом o = Object.create(null); o = >; // эквивалентно этому: o = Object.create(Object.prototype); // В этом примере мы создаём объект с несколькими свойствами. // (Обратите внимание, что второй параметр отображает ключи на *дескрипторы свойств*.) o = Object.create(Object.prototype, // foo является рядовым 'свойством-значением' foo: writable: true, configurable: true, value: "привет" >, // bar является свойством с геттером и сеттером (свойством доступа) bar: configurable: false, get: function () return 10; >, set: function (value) console.log("Установка `o.bar` в", value); >, /* при использовании методов доступа ES5 наш код мог бы выглядеть так: get function() < return 10; >, set function(value) < console.log('Установка `o.bar` в', value); >*/ >, >); function Constructor() > o = new Constructor(); // эквивалентно этому: o = Object.create(Constructor.prototype); // Конечно, если бы в функции Constructor был бы реальный код инициализации, // метод с Object.create() не был бы эквивалентным // создаём новый объект, чей прототип является новым пустым объектом // и добавляем простое свойство 'p' со значением 42 o = Object.create(>, p: value: 42 > >); // по умолчанию свойства НЕ ЯВЛЯЮТСЯ записываемыми, перечисляемыми или настраиваемыми: o.p = 24; o.p; // 42 o.q = 12; for (var prop in o) console.log(prop); > // 'q' delete o.p; // false // для определения свойства ES3 o2 = Object.create( >, p: value: 42, writable: true, enumerable: true, configurable: true, >, >, );
Полифил
Для этого полифила необходима правильно работающая Object.prototype.hasOwnProperty.
if (typeof Object.create != "function") // Этапы производства ECMA-262, издание 5, 15.2.3.5 // Ссылка: http://es5.github.io/#x15.2.3.5 Object.create = (function () // Чтобы сэкономить память, используйте общий конструктор function Temp() > // делает безопасную ссылку на Object.prototype.hasOwnProperty var hasOwn = Object.prototype.hasOwnProperty; return function (O) // 1. Если Type(O) не является Object or Null выдаётся исключение TypeError. if (typeof O != "object") throw TypeError("Object prototype may only be an Object or null"); > // 2. Пусть obj будет результатом создания нового объекта, как если бы // выражение new Object(), где Object является стандартным встроенным // конструктором с таким именем // 3. Установите для внутреннего свойства [[Prototype]] объекта obj значение O. Temp.prototype = O; var obj = new Temp(); Temp.prototype = null; // Давайте не будем держать случайные ссылки на О. // 4. Если аргумент Properties присутствует и не определён, добавляем // собственные свойства к obj, как будто вызывая стандартную встроенную // функцию Object.defineProperties с аргументами obj и // Properties. if (arguments.length > 1) // Object.defineProperties делает ToObject своим первым аргументом. var Properties = Object(arguments[1]); for (var prop in Properties) if (hasOwn.call(Properties, prop)) obj[prop] = Properties[prop]; > > > // 5. Возвращает obj return obj; >; >)(); >
Спецификации
| Specification |
|---|
| ECMAScript Language Specification # sec-object.create |
Совместимость с браузерами
BCD tables only load in the browser
Смотрите также
- Object.defineProperty()
- Object.defineProperties()
- Object.prototype.isPrototypeOf()
- Запись в блоге Джона Резига о getPrototypeOf()
Создание объектов в Javascript
Гибкость Javascript позволяет создавать объекты множеством способов. Но как это нередко случается, разнообразие таит в себе множество подводных камней. Из этой статьи Вы узнаете о том, как разглядеть и обогнуть эти опасные рифы.
Основы основ
Нелишним будет напомнить, что из себя представляют объекты в Javascript и как их можно создавать. Объект в Javascript — это всего лишь хэш-таблица ключей и значений. Если значения представляют собой базовые типы или другие объекты, их называют свойствами, если же это функции, их называют методами объекта.
Объекты, созданные пользователем, можно изменить в любой точке выполнения скрипта. Многие свойства встроенных в язык объектов также изменяемы. То есть можно просто создать пустой объект и добавлять к нему свойства и методы по мере необходимости. Проще всего это сделать с помощью литеральной нотации:
//создаем пустой объект var cat = <>; //добавляем свойство: cat.name = "Garfield"; //или метод: cat.getName = function() < return cat.name; >;
Другим способом создания объекта является использование функций-конструкторов:
// литеральная нотация: var cat = ; // конструктор-функция: var cat = new Object(); cat.name = "Garfield";
Очевидно, что литеральная нотация короче конструктора. Есть и философская причина предпочитать литеральную нотацию конструкторам: она подчеркивает, что объект — это всего лишь изменяемый хэш, а не нечто, создаваемое по шаблону, заданному классом.
Кроме того, использование конструктора Object вынуждает интерпретатор проверять, не переопределена ли эта функция в локальном контексте.
Подводный камень конструктора Object
Причин использовать конструктор Object нет. Но все мы знаем, что иногда приходится использовать какой-то старый код, и в этом случае полезно знать об одной особенности этого конструктора. Он принимает аргумент, и в зависимости от его типа может поручить создание объекта другому встроенному в язык конструктору; в итоге мы получим не тот объект, что ожидали:
//пустой объект var o = new Object(); o.constructor === Object; // true var o = new Object(1); o.constructor === Number; //true var o = new Object("string"); o.constructor === String; //true //мы не предполагали, что созданный объект будет иметь этот метод: typeof o.substring; // "function"
Такое поведение конструктора Object может привести к неожиданным результатам, если мы передаем в него значение, неизвестное на этапе выполнения.
Мораль очевидна: не используйте конструктор Object .
Собственные конструкторы
Мы можем определять собственные конструкторы. Использование их выглядит так:
var cat = new Cat("Garfield"); cat.say(); // "I am Garfield"
Синтаксис похож на конструктор Java, но в Javascript конструктор является обычной функцией и поэтому определяется так:
var Cat = function(name) < this.name = name; this.say = function() < return "I am" + this.name; >>
- создается пустой объект, на который указывает переменная this ; этот объект наследует прототип функции;
- к объекту, хранимому в this , добавляются свойства и методы;
- объект, хранимый в this , неявно возвращается в конце функции (т.к. мы ничего не возвращали явно).
Cat.prototype.say = function() < return "I am " + this.name; >;
Кроме того, не совсем корректно утверждать, что объект this , неявно создаваемый в конструкторе, пуст: он наследуется от прототипа Cat , однако рассмотрение прототипов выходит за рамки этой статьи.
Что возвращает конструктор
При использовании оператора new , конструктор всегда возвращает объект. По умолчанию, это объект, на который ссылается this . Конструктор возвращает this неявно, однако мы можем явно вернуть любой другой объект, например:
var Cat = function() < this.name = "I am Garfield"; var that = <>; that.name = "I am Cat-woman"; return that; >; var cat = new Cat(); cat.name // "I am Cat-woman"
Таким образом, мы можем вернуть из конструктора любое значение, но лишь при условии, что это объект. Если мы попытаемся вернуть, скажем, строку или false , это не приведет к ошибке, но оператор возврата будет проигнорирован, и конструктор вернет this .
Коварный new
Конструкторы — это всего лишь функции, вызываемые с оператором new . Что случится, если забыть этот оператор? Интерпретатор не выдаст предупреждений, но это приведет к логическим ошибкам. Переменная this будет указывать не на объект, унаследованный от прототипа конструктора, а на глобальный объект ( window в случае браузера):
function Cat() < this.name = "Garfield"; >// новый объект var cat = new Cat(); typeof cat; // "object" cat.name; // "Garfield" //забываем new: var cat = Cat(); typeof cat; // "undefined" window.name; // "Garfield"
В строгом режиме стандарта ECMAScript 5 this в этом случае не будет указывать на глобальный объект. Посмотрим, как можно избежать этой ошибки, если ECMAScript 5 недоступен.
Соглашения об именовании функций
Самым простым способом является неукоснительное соблюдение соглашений об именовании функций: начинаем обычные функции со строчной буквы ( myFunction() ), а функции-конструкторы — с заглавной ( MyConstruction() ). К сожалению, такой способ почти ни от чего не спасает.
Явный возврат объекта
Конструкторы могут возвращать любые объекты. Программисты могут воспользоваться этим:
function Cat() < var that = <>; that.name = "Garfield"; return that; >
Имя переменной that выбрано произвольно, это не часть спецификации. С тем же успехом мы можем назвать возвращаемый объект me или self или как Вам заблагорассудится.
Для простых объектов, вроде создаваемого в примере, мы можем вообще обойтись без дополнительных переменных, используя литеральную нотацию:
function Cat() < return < name: "Garfield" >; >
Такой конструктор будет всегда возвращать объект, независимо от того, как его вызывать:
var first = new Cat(), second = Cat(); first.name; // "Garfield" second.name; // "Garfield"
У этого способа есть серьезный недостаток: объект не наследует прототип конструктора, то есть методы и свойства, добавленные непосредственно к Cat , будут недоступны создаваемым с его помощью объектам.
Самовызывающий конструктор
Для решения этой проблемы достаточно проверить, является ли this в теле конструктора экземляром этого самого конструктора, и если нет, вызывать себя снова, но на этот раз с оператором new . Звучит страшно, но на деле просто:
function Cat() < if (!(this instanceof Cat)) < return new Cat(); >this.name = "Garfield"; > Cat.prototype.meow = "Meow!"; var first = new Cat(), second = Cat(); first.name; // "Garfield" second.name; // "Garfield" first.meow; // "Meow!" second.meow; // "Meow!"
Если наш конструктор будет в дальнейшем переименован, придется править его тело. Избежать этого можно проверкой arguments.callee вместо имени конструктора:
if (!(this instanceof arguments.callee))
Здесь мы воспользовались тем, что внутри каждой функции создается объект arguments , содержащий все параметры, передаваемые функции в момент вызова. Свойство callee этого объекта указывает на вызываемую функцию. Но и здесь нужно проявить осторожность: строгий режим ECMAScript 5 вызывает исключение TypeError при обращении к этому свойству, поэтому стоит заранее сделать выбор между удобством рефакторинга и светлым завтра.
Вместо заключения
Javascript — потрясающий язык. Его достаточно легко освоить, а существующие фреймворки позволят без труда использовать его в своих проектах. Но за простотой синтаксиса скрываются целые рифы подводных камней — и очень мощных инструментов. Иногда полезно смотреть, что же там на дне.
Объекты
Как мы знаем из главы Типы данных, в JavaScript существует 8 типов данных. Семь из них называются «примитивными», так как содержат только одно значение (будь то строка, число или что-то другое).
Объекты же используются для хранения коллекций различных значений и более сложных сущностей. В JavaScript объекты используются очень часто, это одна из основ языка. Поэтому мы должны понять их, прежде чем углубляться куда-либо ещё.
Объект может быть создан с помощью фигурных скобок с необязательным списком свойств. Свойство – это пара «ключ: значение», где ключ – это строка (также называемая «именем свойства»), а значение может быть чем угодно.
Мы можем представить объект в виде ящика с подписанными папками. Каждый элемент данных хранится в своей папке, на которой написан ключ. По ключу папку легко найти, удалить или добавить в неё что-либо.
Пустой объект («пустой ящик») можно создать, используя один из двух вариантов синтаксиса:
let user = new Object(); // синтаксис "конструктор объекта" let user = <>; // синтаксис "литерал объекта"
Обычно используют вариант с фигурными скобками <. >. Такое объявление называют литералом объекта или литеральной нотацией.
Литералы и свойства
При использовании литерального синтаксиса <. >мы сразу можем поместить в объект несколько свойств в виде пар «ключ: значение»:
let user = < // объект name: "John", // под ключом "name" хранится значение "John" age: 30 // под ключом "age" хранится значение 30 >;
У каждого свойства есть ключ (также называемый «имя» или «идентификатор»). После имени свойства следует двоеточие «:» , и затем указывается значение свойства. Если в объекте несколько свойств, то они перечисляются через запятую.
В объекте user сейчас находятся два свойства:
- Первое свойство с именем «name» и значением «John» .
- Второе свойство с именем «age» и значением 30 .
Можно сказать, что наш объект user – это ящик с двумя папками, подписанными «name» и «age».
Мы можем в любой момент добавить в него новые папки, удалить папки или прочитать содержимое любой папки.
Для обращения к свойствам используется запись «через точку»:
// получаем свойства объекта: alert( user.name ); // John alert( user.age ); // 30
Значение может быть любого типа. Давайте добавим свойство с логическим значением:
user.isAdmin = true;
Для удаления свойства мы можем использовать оператор delete :
delete user.age;
Имя свойства может состоять из нескольких слов, но тогда оно должно быть заключено в кавычки:
let user = < name: "John", age: 30, "likes birds": true // имя свойства из нескольких слов должно быть в кавычках >;
Последнее свойство объекта может заканчиваться запятой:
let user =
Это называется «висячая запятая». Такой подход упрощает добавление, удаление и перемещение свойств, так как все строки объекта становятся одинаковыми.
Объект, объявленный как константа, может быть изменён
Объект, объявленный через const , может быть изменён.
const user = < name: "John" >; user.name = "Pete"; // (*) alert(user.name); // Pete
Может показаться, что строка (*) должна вызвать ошибку, но нет, здесь всё в порядке. Дело в том, что объявление const защищает от изменений только саму переменную user , а не её содержимое.
Определение const выдаст ошибку только если мы присвоим переменной другое значение: user=. .
Есть ещё один способ сделать константами свойства объекта, который мы рассмотрим в главе Флаги и дескрипторы свойств.
Квадратные скобки
Для свойств, имена которых состоят из нескольких слов, доступ к значению «через точку» не работает:
// это вызовет синтаксическую ошибку user.likes birds = true
JavaScript видит, что мы обращаемся к свойству user.likes , а затем идёт непонятное слово birds . В итоге синтаксическая ошибка.
Точка требует, чтобы ключ был именован по правилам именования переменных. То есть не имел пробелов, не начинался с цифры и не содержал специальные символы, кроме $ и _ .
Для таких случаев существует альтернативный способ доступа к свойствам через квадратные скобки. Такой способ сработает с любым именем свойства:
let user = <>; // присваивание значения свойству user["likes birds"] = true; // получение значения свойства alert(user["likes birds"]); // true // удаление свойства delete user["likes birds"];
Сейчас всё в порядке. Обратите внимание, что строка в квадратных скобках заключена в кавычки (подойдёт любой тип кавычек).
Квадратные скобки также позволяют обратиться к свойству, имя которого может быть результатом выражения. Например, имя свойства может храниться в переменной:
let key = "likes birds"; // то же самое, что и user["likes birds"] = true; user[key] = true;
Здесь переменная key может быть вычислена во время выполнения кода или зависеть от пользовательского ввода. После этого мы используем её для доступа к свойству. Это даёт нам большую гибкость.
let user = < name: "John", age: 30 >; let key = prompt("Что вы хотите узнать о пользователе?", "name"); // доступ к свойству через переменную alert( user[key] ); // John (если ввели "name")
Запись «через точку» такого не позволяет:
let user = < name: "John", age: 30 >; let key = "name"; alert( user.key ); // undefined
Вычисляемые свойства
Мы можем использовать квадратные скобки в литеральной нотации для создания вычисляемого свойства.
let fruit = prompt("Какой фрукт купить?", "apple"); let bag = < [fruit]: 5, // имя свойства будет взято из переменной fruit >; alert( bag.apple ); // 5, если fruit="apple"
Смысл вычисляемого свойства прост: запись [fruit] означает, что имя свойства необходимо взять из переменной fruit .
И если посетитель введёт слово «apple» , то в объекте bag теперь будет лежать свойство .
По сути, пример выше работает так же, как и следующий пример:
let fruit = prompt("Какой фрукт купить?", "apple"); let bag = <>; // имя свойства будет взято из переменной fruit bag[fruit] = 5;
…Но первый пример выглядит лаконичнее.
Мы можем использовать и более сложные выражения в квадратных скобках:
let fruit = 'apple'; let bag = < [fruit + 'Computers']: 5 // bag.appleComputers = 5 >;
Квадратные скобки дают намного больше возможностей, чем запись через точку. Они позволяют использовать любые имена свойств и переменные, хотя и требуют более громоздких конструкций кода.
Подведём итог: в большинстве случаев, когда имена свойств известны и просты, используется запись через точку. Если же нам нужно что-то более сложное, то мы используем квадратные скобки.
Свойство из переменной
В реальном коде часто нам необходимо использовать существующие переменные как значения для свойств с тем же именем.
function makeUser(name, age) < return < name: name, age: age // . другие свойства >; > let user = makeUser("John", 30); alert(user.name); // John
В примере выше название свойств name и age совпадают с названиями переменных, которые мы подставляем в качестве значений этих свойств. Такой подход настолько распространён, что существуют специальные короткие свойства для упрощения этой записи.
Вместо name:name мы можем написать просто name :
function makeUser(name, age) < return < name, // то же самое, что и name: name age // то же самое, что и age: age // . >; >
Мы можем использовать как обычные свойства, так и короткие в одном и том же объекте:
let user = < name, // тоже самое, что и name:name age: 30 >;
Ограничения на имена свойств
Как мы уже знаем, имя переменной не может совпадать с зарезервированными словами, такими как «for», «let», «return» и т.д.
Но для свойств объекта такого ограничения нет:
// эти имена свойств допустимы let obj = < for: 1, let: 2, return: 3 >; alert( obj.for + obj.let + obj.return ); // 6
Иными словами, нет никаких ограничений к именам свойств. Они могут быть в виде строк или символов (специальный тип для идентификаторов, который будет рассмотрен позже).
Все другие типы данных будут автоматически преобразованы к строке.
Например, если использовать число 0 в качестве ключа, то оно превратится в строку «0» :
let obj = < 0: "Тест" // то же самое что и "0": "Тест" >; // обе функции alert выведут одно и то же свойство (число 0 преобразуется в строку "0") alert( obj["0"] ); // Тест alert( obj[0] ); // Тест (то же свойство)
Есть небольшой подводный камень, связанный со специальным свойством __proto__ . Мы не можем установить его в необъектное значение:
let obj = <>; obj.__proto__ = 5; // присвоим число alert(obj.__proto__); // [object Object], значение - это объект, т.е. не то, что мы ожидали
Как мы видим, присвоение примитивного значения 5 игнорируется.
Мы более подробно исследуем особенности свойства __proto__ в следующих главах Прототипное наследование, а также предложим способы исправления такого поведения.
Проверка существования свойства, оператор «in»
В отличие от многих других языков, особенность JavaScript-объектов в том, что можно получить доступ к любому свойству. Даже если свойства не существует – ошибки не будет!
При обращении к свойству, которого нет, возвращается undefined . Это позволяет просто проверить существование свойства:
let user = <>; alert( user.noSuchProperty === undefined ); // true означает "свойства нет"
Также существует специальный оператор «in» для проверки существования свойства в объекте.
"key" in object
Создать пустой объект в JavaScript с помощью <> или new Object ()?
Есть ли разница в том, как движок script обрабатывает их? Есть ли причина использовать один над другим? Аналогичным образом можно создать пустой массив с использованием другого синтаксиса:
var arrayA = [] var arrayB = new Array()
Jonas Pegerfalk 30 окт. 2008, в 21:02
Поделиться
Предупреждение: есть небольшая разница, которая может вызвать очень раздражающие ошибки! Создание пустого объекта с присвоением ему «<>» в прототипе объекта будет одинаковым экземпляром объекта в каждом экземпляре объекта, созданного оператором «new». Хотя вы используете «новый объект (<>)», у вас будут разные экземпляры.
peterh 16 янв. 2015, в 11:35
Стоит отметить, что в дополнение к var objectA = <> var objectB = new Object() существует третья конструкция, которая будет давать тот же результат: var objectC = Object.create(Object.prototype);
kalitsov 26 сен. 2016, в 05:37
<> и [] Используйте <> вместо new Object() . Используйте [] вместо new Array() . Используйте массивы, когда имена членов будут последовательными целыми числами. Используйте объекты, когда имена членов являются произвольными строками или именами. источник
ilgaar 03 июнь 2017, в 11:49
Показать ещё 1 комментарий
Поделиться:
javascript-objects
new-operator
9 ответов
Лучший ответ
Объекты
Нет пользы от использования new Object(); — тогда как <>; может сделать ваш код более компактным и более читаемым.
Для определения пустых объектов они технически одинаковы. Синтаксис <> короче, опережает (меньше Java-ish) и позволяет мгновенно заполнить объект inline — например:
var myObject = < title: 'Frog', url: '/img/picture.jpg', width: 300, height: 200 >;
Массивы
Для массивов аналогично почти невозможно использовать new Array(); over []; — с одним незначительным исключением:
var emptyArray = new Array(100);
создает массив длиной в 100 элементов со всеми слотами, содержащими undefined — которые могут быть приятными/полезными в определенных ситуациях (например, (new Array(9)).join(‘Na-Na ‘) + ‘Batman!’ ).
Моя рекомендация
- Никогда не используйте new Object(); — он clunkier чем ‘<>‘ и выглядит глупо.
- Всегда используйте []; — за исключением случаев, когда вам нужно быстро создать «пустой» массив с предопределенной длиной.
Már Örlygsson 31 окт. 2008, в 00:18
Поделиться
Даже если вы используете синтаксис Array (100), этот же массив в 101-й позиции не определен; единственное, что на самом деле делает число, это изменяет значение свойства длины.
Jason Bunting 31 окт. 2008, в 03:45
Да. новый массив (100); хороший способ сделать это одним вкладышем. . ах . я вижу, что я случайно оставил слово «важный» . отредактирую это.
Már Örlygsson 31 окт. 2008, в 11:48
Array(100) просто неверен, он оставляет массив в недопустимом состоянии, поскольку его длина равна 100, и он равен [] пока вы не начнете добавлять вещи , не делайте этого
Pablo Fernandez 20 авг. 2011, в 15:21
@Pablo нет ничего недействительного в new Array(100) . Прочитайте литературу: developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…
Már Örlygsson 20 авг. 2011, в 17:09
@Már Мар, возьми его у того, кто знает, о чем говорит: javascript.crockford.com/code.html#bonus
Pablo Fernandez 20 авг. 2011, в 17:22
@Pablo Пабло Я понятия не имею, каков твой аргумент. Как и Дуглас Крокфорд, я рекомендую использовать [] . Там нет аргументов. Вы, однако, утверждали, что new Array(100) как-то «недействителен», что неверно.
Már Örlygsson 23 авг. 2011, в 10:59
Этот «ответ» на самом деле является просто мнением и игнорирует реальные различия, заявленные Гильермо.
A.R. 20 нояб. 2013, в 17:41
ОП просит о создании пустых объектов. Гильермо указывает на различия при создании непустых объектов, что является правильным, но не совсем тем, о чем спрашивал ОП.
Már Örlygsson 25 нояб. 2013, в 17:47
new Array(len).fill(0);
Muhammad Umer 11 окт. 2014, в 21:26
Также имейте в виду, что new Array(1,2,3) приводит к [1,2,3] , но new Array(1) не приводит к [1] ; таким образом, семантика Array противоречива и неоправданна.
Dancrumb 29 дек. 2014, в 14:56
Существует очень важное различие: если вы создадите пустой объект, просто присвоив его «<>», он будет таким же. Если вы создадите его с помощью «new Object (<>)», это будет везде другой экземпляр объекта .
peterh 16 янв. 2015, в 11:34
Имейте в виду, что вы можете установить свойство «length» массива следующим образом: var a = []; a.length = 10; что сделало бы массив из 10 неопределенных элементов.
jaySon 25 окт. 2015, в 20:24
Я нахожу новый Object () более читабельным, чем <>. Сказать, что это глупо и глупо, звучит для меня элитарно.
Mark 04 май 2016, в 19:39
Я бы добавил, что Object.create(null) может быть полезен для создания пустого объекта, тогда как < >наследуется от прототипа Object.
Meow 15 сен. 2016, в 18:45
Хороший вопрос об Object.create(null) .
Már Örlygsson 16 дек. 2016, в 13:41
Показать ещё 13 комментариев
Да, есть разница, они не то же самое. Это правда, что вы получите те же результаты, но двигатель работает по-другому для них обоих. Один из них является литералом объекта, а другой — конструктором, двумя разными способами создания объекта в javascript.
var objectA = <> //This is an object literal var objectB = new Object() //This is the object constructor
В JS все является объектом, но вы должны знать следующее о новом объекте(): он может принимать параметр, и в зависимости от этого параметра он создаст строку, число или просто пустую объект.
Например: new Object(1) , вернет номер. new Object(«hello») вернет строку, это означает, что конструктор объекта может делегировать -разложение параметра — создание объекта для других конструкторов, таких как строка, число и т.д. Очень важно помнить об этом, когда вы управляете динамические данные для создания объектов.
Многие авторы рекомендуют не использовать конструктор объекта, если вместо этого вы можете использовать определенную литературную нотацию, где вы будете уверены, что то, что вы создаете, — это то, что вы ожидаете иметь в своем коде.
Я предлагаю вам продолжить чтение различий между литералами и конструкторами на javascript, чтобы найти более подробную информацию.
Guillermo Snipe 14 апр. 2011, в 15:04
Поделиться
Буквальные обозначения на самом деле более читабельны и лаконичны для создания динамических объектов данных.
Sid 06 авг. 2017, в 08:35
У них одинаковый конечный результат, но я бы просто добавил, что использование синтаксиса literal может помочь вам привыкнуть к синтаксису JSON (строковое подмножество синтаксиса объектного литерала JavaScript), поэтому это может быть хорошая практика Попасть в.
Еще одно: у вас могут быть тонкие ошибки, если вы забудете использовать оператор new . Таким образом, использование литералов поможет вам избежать этой проблемы.
В конечном счете, это будет зависеть от ситуации, а также от предпочтения.
