Я знаю много способов создания объектов JS, но я не знал ни Object.create(null)
одного.
Вопрос:
это точно так же, как:
var p = {}
против
var p2 = Object.create(null);
?
источник
Я знаю много способов создания объектов JS, но я не знал ни Object.create(null)
одного.
Вопрос:
это точно так же, как:
var p = {}
против
var p2 = Object.create(null);
?
Они не эквивалентны. {}.constructor.prototype == Object.prototype
В то время Object.create(null)
как не наследует от чего-либо и, следовательно, не имеет никаких свойств.
Другими словами: объект Javascript наследует от объекта по умолчанию, если вы явно не создавать его с нулем в качестве прототипа, как: Object.create(null)
.
{}
вместо этого будет эквивалентно Object.create(Object.prototype)
.
В Chrome Devtool вы можете видеть, что Object.create(null)
не имеет __proto__
свойства, а {}
есть.
Они определенно не эквивалентны. Я пишу этот ответ, чтобы более полно объяснить, почему он имеет значение.
var p = {};
Создает объект, который наследует свойства и методы от Object
.
var p2 = Object.create(null);
Создает объект, который ничего не наследует.
Если вы используете объект в качестве карты и создаете объект, используя метод 1, описанный выше, то вам нужно быть очень осторожным при поиске на карте. Поскольку свойства и методы from Object
наследуются, ваш код может столкнуться с ситуацией, когда на карте есть ключи, которые вы никогда не вставляли. Например, если вы выполнили поиск toString
, вы найдете функцию, даже если вы никогда не указали это значение. Вы можете обойти это так:
if (Object.prototype.hasOwnProperty.call(p, 'toString')) {
// we actually inserted a 'toString' key into p
}
Обратите внимание, что можно назначить что-то p.toString
, просто переопределит унаследованную toString
функцию p
.
Обратите внимание, что вы не можете просто сделать это, p.hasOwnProperty('toString')
потому что вы, возможно, вставили ключ "hasOwnProperty" p
, поэтому мы заставляем его использовать реализацию в Object
.
С другой стороны, если вы используете описанный выше метод 2, вам не придется беспокоиться о том, что что-то Object
появится на карте.
Вы не можете проверить существование свойства с помощью простого if
:
// Unreliable:
if (p[someKey]) {
// ...
}
Значением может быть пустая строка, может быть false
, или null
, или undefined
, или 0
, или NaN
, и т. Д. Чтобы проверить, существует ли свойство вообще, вам все равно придется использовать Object.prototype.hasOwnProperty.call(p, someKey)
.
if (someKey in p) {
Object.create(null)
. Я предпочитаю не делать подобных предположений, даже если вы были абсолютно правы в том, что он использовалObject.create(null)
, код может измениться, объект может быть заменен на объект, который наследуетObject
в какой-то момент.hasOwnProperty
всегда работает.{}
том, что он настолько распространенObject.create(null)
, что если ваш код случайно захватит унаследованное свойство в этот момент, вы, вероятно, будете беспокоиться о более крупных ошибках. Я вижу только людей, использующих Object.create (null) в качестве незначительной оптимизации.!!p[key]
хорошо работает сObject.create(null)
. НоhasKey = (key, input) => Object.prototype.hasOwnProperty.call(input, key)
тоже неплохоp
потому что каждый метод может быть вставлен и поэтому становится небезопасным.При создании объектов с помощью
{}
объекта создается объект, прототипObject.prototype
которого наследует основные функции отObject
прототипа, а при создании объектов с помощьюObject.create(null)
объекта создается пустой объект, прототип которого равен нулю.источник
Если кто-то ищет реализацию
Object.create(null)
, просто чтобы узнать, как она работает. Он написан с использованием__proto__
нестандартных и, следовательно, я не рекомендую его .Примечание : я написал это из любопытства, и оно написано только в простых терминах, например, я не переношу дескрипторы свойств из второго объекта в возвращаемый объект.
источник
__proto__
теперь официально будет частью языка.-1
вarguments.length>0?arguments[0]:-1;
?Object
прототип сохраняется, если не указан первый аргумент. Имена переменных могли бы быть намного лучше здесь.Когда вы создаете объект с Object.create (null), это означает, что вы создаете объект без прототипа. Здесь null означает конец цепочки прототипов. Тем не менее, когда вы создаете объект наподобие {}, будет добавлен прототип объекта. Следовательно, это два разных объекта, один с прототипом, другой без прототипа. Надеюсь, это поможет
источник