Существует только 3 строки кода, и все же я испытываю затруднения, полностью схватывая это:
Object.create = function (o) {
function F() {}
F.prototype = o;
return new F();
};
newObject = Object.create(oldObject);
Object.create()
начинается путем создания пустой вызванной функции F
. Я думаю, что функция является своего рода объектом.Где это F
объект хранится? Глобально я предполагаю.
Затем наш oldObject
, переданный в как o
, становится прототипом функции F
. Функция (т.е. объект) F
теперь "наследовался" нашему oldObject
, в том смысле, что определение имен направит через него. Хороший, но мне любопытно, что прототип по умолчанию для объекта, Объекта? Это также верно для функционального объекта?
Наконец, F
инстанцирован и возвращен, становясь нашим newObject
. new
операция, строго необходимая здесь? Не делает F
уже обеспечьте то, в чем мы нуждаемся, или существует ли критическое различие между функциональными объектами и нефункциональными объектами? Очевидно не будет возможно иметь функцию конструктора с помощью этой техники.
Что происходит в следующий раз Object.create()
назван? Глобальная функция F
перезаписанный? Конечно, это не снова используется, потому что это изменило бы ранее настроенные объекты. И что происходит, если несколько потоков звонят Object.create()
, есть ли любой вид синхронизации для предотвращения условий состязания на F
?
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), поэтому я бы порекомендовал вам хотя бы проверить, существует ли собственная реализация, прежде чем отменять ее.
1) Функция действительно является разновидностью объекта. Объект функции с идентификатором F
создается каждый раз, когда вызывается Object.create
, и доступен с этим идентификатором только в рамках данного выполнения Object.create
. Поэтому каждый раз, когда вызывается Object.create
, вы получаете другой объект функции F
. Этот функциональный объект продолжает жить как конструктор
свойства объекта, возвращаемого Object.create
.
2)
F теперь "наследует" от нашего oldObject, в том смысле, что разрешение имен будет проходить через него
Это не совсем верно. Присвоение объекта someObject
свойству prototype
функции просто означает, что прототипом любого будущего объекта, созданного вызовом этой функции в качестве конструктора, будет someObject
.
3) Свойство new
абсолютно жизненно важно для этой техники. Только при вызове функции в качестве конструктора создается новый объект, а прототип этого объекта (который обычно недоступен) устанавливается в свойство prototype
функции-конструктора. Другого (стандартизованного) способа установить прототип объекта не существует.
Наконец, JavaScript в браузерах является однопоточным, поэтому такие условия гонки, как вы описали, невозможны.
Ваше основное непонимание здесь в том, что F имеет глобальную область видимости. Он объявлен в теле Object.create и, следовательно, имеет область видимости только в пределах этого блока методов.