2012-04-13 13 views
9

Czytałem na podkładce Crockford, aby zapobiec nadpisywaniu prototypów i rozumiem, że nie jest to rozwiązanie typu end-all/be-all. Rozumiem również, że ES5 Shim może być realną alternatywą dla tego. Czytałem również this post which provides a more robust, secure alternative.Zrozumienie obiektu obiektu Crockford.create shim

Nadal chciałbym wiedzieć, co jego podkładka "mówi", a następnie "robi". Czy ktoś może mi powiedzieć, czy moje wyjaśnienia są poprawne?

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. 

ten sposób prototyp „marionetką” obiektu nie mogą być nadpisane kiedy powiększać rzeczy do „another_stooge”. Nie trzeba resetować prototypu "stooge" za pomocą "konstruktora".

Dzięki z góry,

-k

Odpowiedz

14
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 

W powyższym przykładzie utworzyliśmy nowy obiekt newObject użyciu create metodę, która jest funkcją członkiem Object obiektu, który dodaliśmy w obiekcie Object wcześniej w naszym przykładzie (Crockforda'S). Więc w zasadzie to, co robi to, że metoda deklaruje funkcję , pustego obiektu every function is a first class object in javascript, a następnie odziedziczyliśmy prototyp o (w tym przypadku o jest również obiektem oldObject przekazanym jako parametr metody tworzenia) i ostatecznie zwróciliśmy nowy obiekt (instancja F) przy użyciu return new F(); do zmiennej newObject, więc teraz newObject jest obiektem, który odziedziczył oldObject. Teraz, jeśli napiszesz console.log(newObject.prop);, to wypisze Property_one, ponieważ nasz obiekt newObject odziedziczył oldObject i dlatego otrzymaliśmy wartość prop jako Property_one. jest to znane jako prototypowe dziedziczenie.

Musisz przekazać obiekt jako parametr create metody

+0

A-ha! Myślę, że rozumiem. Dzięki Szejkowi ... twoja pomoc jest bardzo ceniona !!! – kaidez

+0

Jesteś bardzo zadowolony :-) –

0

Wszystko robi to stworzenie nowego konstruktora obiektu, który jest F, to następnie przypisać obiekt przeszedł na własność prototypu konstruktor tak, że nowy obiekt utworzony z Konstruktor F dziedziczy te metody.

Następnie za pomocą konstruktora powrotu obiektu nowo zainicjowana (New F() => F.prototype)

ale z Crockforda jeden nie przypisać konstruktora poprawnie normalnie nowy konstruktor przedmiot powinien być taki sam jako konstruktor obiektu, z którego dziedziczy.

+0

Hi gillesc. Dziękuję za odpowiedź! Więc kiedy to jest używane, czy to oznacza, że ​​prototyp konstruktora musi zostać zresetowany? Coś jak: stooge.prototype.constructor = stooge; Jeszcze raz dziękuję! – kaidez

0

Na komentarze:

> //Object.create equals an anonymous function that accepts one parameter, 'o'. 

Lepiej powiedzieć, że funkcja jest przypisana do właściwości Objectcreate. Wszystkie funkcje można uznać za anonimowe, tylko niektóre są przypisane do nazwanych właściwości lub zmiennych, inne nie.

> //Create a new function called 'F' which is just an empty object. 

Zadeklaruj funkcję. Tak, to też jest obiekt.

>  F.prototype = o; 
>  //the prototype of the 'F' function should point to the 
>  //parameter of the anonymous function. 

Odniesienie do o jest przypisany do F.prototype jest nieco krótsza pisać.

>  //create a new constructor function based off of the 'F' function. 

Nie, powinno być "Zwróć instancję F". Tak zwrócony obiekt ma wewnętrzny [[Prototype]], który odwołuje się do obiektu przekazanego do funkcji. Problem polega na tym, że do wykonania triku trzeba utworzyć niepotrzebną funkcję F, a konstruktor zwracanego obiektu nie będzie miał użytecznej wartości, ponieważ odwołuje się do pustego F.

Nie znaczy to, że właściwość konstruktora jest bardzo niezawodna lub szczególnie użyteczna w normalny sposób.

ten sposób prototyp „marionetką” obiektu nie mogą być nadpisane kiedy powiększać rzeczy do „another_stooge”. Nie trzeba resetować prototypu "stooge" za pomocą "konstruktora".

To dziwne stwierdzenie. * another_stooge * ma stooge ponieważ jest prywatne [[Prototype]], nie dziedziczy po stooge.prototype, ale od stooge.[[Prototype]].

Jeśli chcesz, aby another_stooge odziedziczył po stooge.prototype, użyj Object.create(stooge.prototype) lub Object.create(new stooge()), ten pierwszy jest prawdopodobnie bardziej odpowiedni.

Mam nadzieję, że wszystko ma sens.

+0

Cześć RobG. Dziękuję za odpowiedź! Muszę ponownie przeczytać pełną składnię, ale z pewnością wiem więcej niż godzinę temu. Dzięki jeszcze raz! – kaidez

0

Istnieją dwie sztuczki tutaj:

  1. F nie jest prosta funkcja, to konstruktor.
  2. "F.prototype" to po prostu własność, w tej chwili nic nie robi z dziedziczeniem. Prawdziwą sztuczką jest to, że kiedy używamy "nowego F()", "nowy" tworzy nowy obiekt, wywołuje konstruktora (który nic tu nie robi) ORAZ ustawia wewnętrzny "prototyp" nowego obiektu o wartości "F.prototype", więc zwracany obiekt odziedziczy po "o".

Więc myślę, że:

  • F jest konstruktor
  • F nie dziedziczą o
  • "nowej F" (który jest zwrócony obiekt) jest dziedziczą z o
-1

Chyba nazywanie funkcji wewnętrznej jako Object zamiast F powoduje, że obiekt wynikowy wygląda bliżej tego, co Object.create() ould stworzyć.

if (typeof Object.create !== 'function') { 
    Object.create = function (o) { 
     function Object() {} 
     Object.prototype = o; 
     return new Object(); 
    }; 
} 
Powiązane problemy