Что происходит в методе создания объекта Crockford?

Существует только 3 строки кода, и все же я испытываю затруднения, полностью схватывая это:

Object.create = function (o) {
    function F() {}
    F.prototype = o;
    return new F();
};
newObject = Object.create(oldObject);

(от наследования Prototypal)

  1. Object.create() начинается путем создания пустой вызванной функции F. Я думаю, что функция является своего рода объектом.Где это F объект хранится? Глобально я предполагаю.

  2. Затем наш oldObject, переданный в как o, становится прототипом функции F. Функция (т.е. объект) F теперь "наследовался" нашему oldObject, в том смысле, что определение имен направит через него. Хороший, но мне любопытно, что прототип по умолчанию для объекта, Объекта? Это также верно для функционального объекта?

  3. Наконец, F инстанцирован и возвращен, становясь нашим newObject. new операция, строго необходимая здесь? Не делает F уже обеспечьте то, в чем мы нуждаемся, или существует ли критическое различие между функциональными объектами и нефункциональными объектами? Очевидно не будет возможно иметь функцию конструктора с помощью этой техники.

Что происходит в следующий раз Object.create() назван? Глобальная функция F перезаписанный? Конечно, это не снова используется, потому что это изменило бы ранее настроенные объекты. И что происходит, если несколько потоков звонят Object.create(), есть ли любой вид синхронизации для предотвращения условий состязания на F?

25
задан Kevin Brown 20 February 2015 в 02:10
поделиться

3 ответа

1) Object.create () начинается с создания пустой функции с именем F. Я думаю, что функция - это своего рода объект. Где хранится этот объект F ? Думаю, глобально.

Нет, он хранится в локальной области видимости функции Object.create , каждый раз, когда вы вызываете Object.create , эта функция F будет воссоздаваться.

Вы даже можете создать реализацию с более эффективным использованием памяти, сохранив F при закрытии и повторно используя его:

if (typeof Object.create !== "function") {
  Object.create = (function () {
    function F() {} // created only once
    return function (o) {
      F.prototype = o; // reused on each invocation
      return new F();
    };
  })();
}

2) Затем наш oldObject, переданный как o, становится прототипом функции F. Функция (т. е. объект) F теперь "наследуется" от нашего oldObject в том смысле, что разрешение имени будет маршрутизировать через это. Хорошо, но мне любопытно, какой прототип по умолчанию для объекта , Object? Это также верно для объекта-функции?

Все объекты имеют внутреннее свойство, которое строит цепочку прототипов, это свойство известно как [[Prototype]] , это внутреннее свойство, хотя некоторые реализации позволяют получить к нему доступ, например mozilla, с помощью свойства obj .__ proto __ .

Значение по умолчанию [[Prototype]] при создании нового объекта, то есть var obj = {}; равно Object.prototype .

Все функции имеют свойство prototype , это свойство используется, когда функция используется в качестве конструктора , вызываемого с помощью оператора new .

Новый экземпляр объекта создается за кулисами, и для этого объекта [[Prototype]] устанавливается свойство prototype его конструктора.

3) Наконец, создается экземпляр F и возвращается , становясь нашим новым объектом. Здесь строго необходима "новая" операция ? Разве F еще не предоставляет то, что нам нужно, или существует критическая разница между объектами-функциями и объектами, не являющимися функциями? Ясно, что невозможно создать функцию-конструктор , использующую этот метод .

Да, в этом методе очень важен оператор new .

Оператор new - единственный стандартный способ установить внутреннее свойство [[Prototype]] объекта. Если вам интересно, как это работает, вы можете указать см. внутреннюю операцию [[Construct]] .

Что произойдет при следующем вызове Object.create ()? Перезаписана глобальная функция F ? Разумеется, он не используется повторно, потому что это изменит ранее настроенные объекты. И что произойдет, если несколько потоков вызовут Object.create (), есть ли какая-то синхронизация для предотвращения условий гонки на F?

в следующий раз, когда вызывается Object.create , новая локальная функция F создается только в рамках вызова метода, вам не следует беспокоиться об условиях гонки .

Обратите внимание, что эта реализация вряд ли соответствует объекту .create , описанный в ECMAScript 5th Edition Specification , в этом методе вы можете передать дескриптор свойства для инициализации объекта.

Все поставщики браузеров реализуют его (уже доступны в альфа-версиях Firefox 3.7, последних версиях Wekit Nightly Builds и Chrome 5 Beta), поэтому я бы порекомендовал вам хотя бы проверить, существует ли собственная реализация, прежде чем отменять ее.

29
ответ дан 28 November 2019 в 21:15
поделиться

1) Функция действительно является разновидностью объекта. Объект функции с идентификатором F создается каждый раз, когда вызывается Object.create, и доступен с этим идентификатором только в рамках данного выполнения Object.create. Поэтому каждый раз, когда вызывается Object.create, вы получаете другой объект функции F. Этот функциональный объект продолжает жить как конструктор свойства объекта, возвращаемого Object.create.

2)

F теперь "наследует" от нашего oldObject, в том смысле, что разрешение имен будет проходить через него

Это не совсем верно. Присвоение объекта someObject свойству prototype функции просто означает, что прототипом любого будущего объекта, созданного вызовом этой функции в качестве конструктора, будет someObject.

3) Свойство new абсолютно жизненно важно для этой техники. Только при вызове функции в качестве конструктора создается новый объект, а прототип этого объекта (который обычно недоступен) устанавливается в свойство prototype функции-конструктора. Другого (стандартизованного) способа установить прототип объекта не существует.

Наконец, JavaScript в браузерах является однопоточным, поэтому такие условия гонки, как вы описали, невозможны.

7
ответ дан 28 November 2019 в 21:15
поделиться

Ваше основное непонимание здесь в том, что F имеет глобальную область видимости. Он объявлен в теле Object.create и, следовательно, имеет область видимости только в пределах этого блока методов.

2
ответ дан 28 November 2019 в 21:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: