Понимание крокер-объекта 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();
    };
}