Zoeken…


Standaard functieprototype

Begin met het definiëren van een Foo functie die we als constructor zullen gebruiken.

function Foo (){}

Door Foo.prototype bewerken, kunnen we eigenschappen en methoden definiëren die door alle instanties van Foo worden gedeeld.

Foo.prototype.bar = function() {
  return 'I am bar';
};

We kunnen vervolgens een instantie maken met behulp van het new trefwoord en de methode aanroepen.

var foo = new Foo();

console.log(foo.bar()); // logs `I am bar`

Verschil tussen Object.key en Object.prototype.key

In tegenstelling tot talen als Python worden statische eigenschappen van de constructorfunctie niet overgenomen van instanties. Instanties erven alleen van hun prototype, dat erft van het prototype van het bovenliggende type. Statische eigenschappen worden nooit geërfd.

function Foo() {};
Foo.style = 'bold';

var foo = new Foo();

console.log(Foo.style); // 'bold'
console.log(foo.style); // undefined

Foo.prototype.style = 'italic';

console.log(Foo.style); // 'bold'
console.log(foo.style); // 'italic'

Nieuw object van prototype

In JavaScript kan elk object het prototype van een ander zijn. Wanneer een object wordt gemaakt als een prototype van een ander, neemt het alle eigenschappen van de bovenliggende objecten over.

var proto = { foo: "foo", bar: () => this.foo };

var obj = Object.create(proto);

console.log(obj.foo);
console.log(obj.bar());

Console-uitgang:

> "foo"
> "foo"

OPMERKING Object.create is beschikbaar via ECMAScript 5, maar hier is een polyfill als u ondersteuning nodig hebt voor ECMAScript 3

if (typeof Object.create !== 'function') {
    Object.create = function (o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
}

Bron: http://javascript.crockford.com/prototypal.html


Object.create ()

De methode Object.create () maakt een nieuw object met het opgegeven prototypeobject en de eigenschappen.

Syntaxis: Object.create(proto[, propertiesObject])

Parameters :

  • proto (Het object dat het prototype van het nieuw gemaakte object moet zijn.)
  • propertiesObject (optioneel. Indien gespecificeerd en niet ongedefinieerd, specificeert een object waarvan de ontelbare eigen eigenschappen (dat wil zeggen die eigenschappen die op zichzelf zijn gedefinieerd en niet de ontelbare eigenschappen in de prototypeketen) eigenschapsbeschrijvingen die moeten worden toegevoegd aan het nieuw gemaakte object, met de bijbehorende eigenschapnamen. Deze eigenschappen komen overeen met het tweede argument van Object.defineProperties ().)

Winstwaarde

Een nieuw object met het opgegeven prototypeobject en eigenschappen.

Uitzonderingen

Een uitzondering TypeError als de parameter proto niet null of een object is.

Prototypische erfenis

Stel dat we een eenvoudig object hebben dat prototype :

var prototype = { foo: 'foo', bar: function () { return this.foo; } };

Nu willen we een ander object genaamd obj dat van het prototype erft, wat hetzelfde is als zeggen dat prototype het prototype van obj

var obj = Object.create(prototype);

Nu zijn alle eigenschappen en methoden van prototype beschikbaar voor obj

console.log(obj.foo);
console.log(obj.bar());

Console-uitgang

"foo"
"foo"

Prototypische overerving vindt plaats via interne verwijzingen naar objecten en objecten kunnen volledig worden gewijzigd. Dit betekent dat elke wijziging die u aanbrengt in een prototype, onmiddellijk van invloed zal zijn op elk ander object waarvan het prototype een prototype is.

prototype.foo = "bar";
console.log(obj.foo);

Console-uitgang

"bar"

Object.prototype is het prototype van elk object, dus het wordt ten zeerste aanbevolen dat je er niet mee knoeit, vooral als je een bibliotheek van derden gebruikt, maar we kunnen er een beetje mee spelen.

Object.prototype.breakingLibraries = 'foo';
console.log(obj.breakingLibraries);
console.log(prototype.breakingLibraries);

Console-uitgang

"foo"
"foo"

Leuk feit dat ik de browserconsole heb gebruikt om deze voorbeelden te maken en deze pagina heb verbroken door die eigenschap breakingLibraries toe te voegen.


Pseudo-klassieke erfenis

Het is een emulatie van klassieke erfenis met behulp van prototypische erfenis die laat zien hoe krachtig prototypes zijn. Het is gemaakt om de taal aantrekkelijker te maken voor programmeurs uit andere talen.

6

BELANGRIJKE OPMERKING : sinds ES6 heeft het geen zin om pseudo-calssische overerving te gebruiken, omdat de taal conventionele klassen simuleert. Als u ES6 niet gebruikt, zou u dat moeten doen . Als u nog steeds het klassieke overervingspatroon wilt gebruiken en u zich in een ECMAScript 5 of lagere omgeving bevindt, is pseudoklassiek uw beste keuze.

Een "klasse" is gewoon een functie die is gemaakt om met de new operand te worden aangeroepen en die als constructor wordt gebruikt.

function Foo(id, name) {
    this.id = id;
    this.name = name;
}

var foo = new Foo(1, 'foo');
console.log(foo.id);

Console-uitgang

1

foo is een instantie van Foo. De JavaScript-coderingsconventie zegt dat als een functie begint met een hoofdletter, deze als constructor (met de new operand) kan worden aangeroepen.


Om eigenschappen of methoden toe te voegen aan de "klasse" moet u ze toevoegen aan het prototype, dat u kunt vinden in de eigenschap prototype van de constructor.

Foo.prototype.bar = 'bar';
console.log(foo.bar);

Console-uitgang

bar

Wat Foo doet als een "constructor" is gewoon objecten maken met Foo.prototype als prototype.


U kunt op elk object een verwijzing naar de constructor vinden

console.log(foo.constructor);

functie Foo (id, naam) {...

console.log({ }.constructor);

function Object () {[native code]}

En controleer ook of een object een instantie van een bepaalde klasse is met de operator instanceof

console.log(foo instanceof Foo);

waar

console.log(foo instaceof Object);

waar

Het prototype van een object instellen

5

Met ES5 + kan de functie Object.create worden gebruikt om een object te maken met elk ander object als prototype.

const anyObj = {
    hello() {
        console.log(`this.foo is ${this.foo}`);
    },
};

let objWithProto = Object.create(anyObj);
objWithProto.foo = 'bar';

objWithProto.hello(); // "this.foo is bar"

Als u expliciet een object zonder een prototype wilt maken, gebruikt u null als prototype. Dit betekent dat het object ook niet van Object.prototype zal erven en nuttig is voor objecten die worden gebruikt voor het controleren van woordenboeken, bijv

let objInheritingObject = {};
let objInheritingNull = Object.create(null);

'toString' in objInheritingObject; // true
'toString' in objInheritingNull ; // false
6

Vanaf ES6 kan het prototype van een bestaand object bijvoorbeeld worden gewijzigd met Object.setPrototypeOf

let obj = Object.create({foo: 'foo'});
obj = Object.setPrototypeOf(obj, {bar: 'bar'});

obj.foo; // undefined
obj.bar; // "bar"

Dit kan bijna overal worden gedaan, inclusief op this object of in een constructor.

Opmerking: dit proces is erg traag in de huidige browsers en moet met mate worden gebruikt, probeer in plaats daarvan het object met het gewenste prototype te maken.

5

Vóór ES5 was de enige manier om een object met een handmatig gedefinieerd prototype te maken, het bijvoorbeeld met new te bouwen

var proto = {fizz: 'buzz'};

function ConstructMyObj() {}
ConstructMyObj.prototype = proto;

var objWithProto = new ConstructMyObj();
objWithProto.fizz; // "buzz"

Dit gedrag is dicht genoeg bij Object.create dat het mogelijk is om een polyfill te schrijven.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow