Понимание крокер-объекта Object.create shim
Я читал обложку Crockford для предотвращения перезаписи прототипов и понимал, что это не решение "все-все-все-все". Я также понимаю, что ES5 Shim может быть жизнеспособной альтернативой этому. Я также читаю этот пост, который обеспечивает более надежную и безопасную альтернативу.
Тем не менее, я хотел бы знать, что его Object.create
прокладка "говорит", а затем "делает". Может кто-нибудь, пожалуйста, скажите, правильно ли написаны мои комментарии?
if (typeof Object.create === 'undefined') {
//If the browser doesn't support Object.create
Object.create = function (o) {
//Object.create equals an anonymous function that accepts one parameter, 'o'.
function F() {};
//Create a new function called 'F' which is just an empty object.
F.prototype = o;
//the prototype of the 'F' function should point to the
//parameter of the anonymous function.
return new F();
//create a new constructor function based off of the 'F' function.
};
}
//Then, based off of the 'Lost' example in the Crockford book...
var another_stooge = Object.create(stooge);
//'another_stooge' prototypes off of 'stooge' using new school Object.create.
//But if the browser doesn't support Object.create,
//'another_stooge' prototypes off of 'stooge' using the old school method.
Таким образом, прототип объекта "stooge" нельзя перезаписать, когда мы добавим материал в "another_stooge". Не нужно reset прототипа 'stooge', используя 'конструктор'.
Спасибо заранее,
-k
Ответы
Ответ 1
if (typeof Object.create !== 'function') {
Object.create = function (o) {
function F() {}
F.prototype = o;
return new F();
};
}
var oldObject={prop:'Property_one' }; // An object
var newObject = Object.create(oldObject); // Another object
В приведенном выше примере мы создали новый объект newObject
с использованием метода create
, который является функцией-членом объекта Object
, который мы добавили в объект Object
ранее в нашем примере (Crockford's), Поэтому в основном то, что метод create
объявляет функцию F
, пустой объект every function is a first class object in javascript
, а затем мы унаследовали прототип o
(в этом случае o
также является объектом oldObject
передается как параметр метода create), и, наконец, мы вернули новый объект (экземпляр F) с помощью return new F();
в переменную newObject
, поэтому теперь newObject
является объектом, унаследовавшим oldObject
, Теперь, если вы напишете console.log(newObject.prop);
, тогда он выведет Property_one
, потому что наш объект newObject
унаследовал oldObject
и поэтому мы получили значение prop
как Property_one
. это называется прототипическим наследованием.
Вы должны передать объект в качестве параметра метода create
Ответ 2
Все, что он делает, это создать новый конструктор объектов, который является F, затем назначить переданный объект свойству прототипа конструктора, чтобы новый объект, созданный с помощью конструктора F, наследовал эти методы.
Затем он использует конструктор для возврата нового объекта инициализации (новый F() = > F.prototype)
Но crockford не может переназначить конструктор должным образом, как обычно новый конструктор объекта должен быть таким же, как и конструктор объекта, на который он наследует.
Ответ 3
В ваших комментариях:
> //Object.create equals an anonymous function that accepts one parameter, 'o'.
Лучше сказать, что функция присваивается свойству create
Object
. Все функции можно считать анонимными, только некоторые из них назначаются именованным свойствам или переменным, другие - нет.
> //Create a new function called 'F' which is just an empty object.
Объявить функцию. Да, это тоже объект.
> F.prototype = o;
> //the prototype of the 'F' function should point to the
> //parameter of the anonymous function.
Ссылка на o
присваивается F.prototype
немного короче для записи.
> //create a new constructor function based off of the 'F' function.
Нет, должен быть "Вернуть экземпляр F". Таким образом, возвращаемый объект имеет внутренний [[Prototype]]
, который ссылается на объект, переданный функции. Беспокойная часть заключается в том, что для выполнения трюка необходимо создать бесполезную функцию F, а возвращаемый объект-конструктор не будет иметь полезного значения, поскольку он ссылается на пустой F
.
Не то, чтобы свойство конструктора было очень надежным или особенно полезным в любом случае.
Таким образом, прототип объекта 'stooge' не может быть перезаписан когда мы добавляем материал в "another_stooge". Нет необходимости resetпрототип 'stooge' с использованием "конструктора".
Это странное утверждение. * another_stooge * имеет stooge
как private [[Prototype]]
, он не наследуется от stooge.prototype
, а от stooge.[[Prototype]]
.
Если вы хотите, чтобы another_stooge
наследовал от stooge.prototype
, используйте Object.create(stooge.prototype)
или Object.create(new stooge())
, вероятно, более вероятно, что это первый вариант.
Я надеюсь, что все имеет смысл.
Ответ 4
Здесь есть два трюка:
- F не является простой функцией, это конструктор.
- "F.prototype" - это просто свойство, он ничего не делает с наследованием в этот момент.
Реальный трюк заключается в том, что, когда мы используем "новый F()", "новый" создает новый объект, вызывает конструктор (который здесь ничего не делает) И устанавливает новый внутренний объект "prototype" в поле с значением "F.prototype", поэтому возвращаемый объект наследуется от "o".
Итак, я думаю, что:
- F - конструктор
- F не наследуется от o
- "новый F" (который является возвращенным объектом) наследуется от o
Ответ 5
Я предполагаю, что имя внутренней функции как Object
вместо F
делает результирующий объект ближе к тому, что создавал Object.create()
.
if (typeof Object.create !== 'function') {
Object.create = function (o) {
function Object() {}
Object.prototype = o;
return new Object();
};
}