Wat is het ‘nieuwe’ zoekwoord in JavaScript?

Het newtrefwoord in JavaScript kan nogal verwarrend zijn wanneer het voor het eerst wordt aangetroffen, omdat mensen geneigd zijn te denken dat JavaScript geen objectgeoriënteerde programmeertaal is.

  • Wat is het?
  • Welke problemen lost het op?
  • Wanneer is het gepast en wanneer niet?

Antwoord 1, autoriteit 100%

Het doet 5 dingen:

  1. Het maakt een nieuw object aan. Het type van dit object is gewoon object.
  2. Het stelt de interne, ontoegankelijke eigenschap [[prototype]](dwz __proto__) van dit nieuwe object in als het externe, toegankelijke prototypeobject (elk functieobject heeft automatisch een prototypeeigenschap).
  3. Het zorgt ervoor dat de variabele thisnaar het nieuw gemaakte object wijst.
  4. Het voert de constructorfunctie uit, waarbij het nieuw gemaakte object wordt gebruikt wanneer thiswordt genoemd.
  5. Het retourneert het nieuw gemaakte object, tenzij de constructorfunctie een niet-nullobjectreferentie retourneert. In dit geval wordt in plaats daarvan die objectreferentie geretourneerd.

Opmerking: constructorfunctieverwijst naar de functie na het trefwoord new, zoals in

new ConstructorFunction(arg1, arg2)

Zodra dit is gedaan en een ongedefinieerde eigenschap van het nieuwe object wordt aangevraagd, zal het script in plaats daarvan het object [[prototype]]van het object controleren op de eigenschap. Dit is hoe je iets kunt krijgen dat lijkt op traditionele klasse-overerving in JavaScript.

Het moeilijkste deel hierover is puntnummer 2. Elk object (inclusief functies) heeft dit interne eigendom genaamd [[prototype]] . Het kan alleen worden ingesteld op het maken van objecten, hetzij met NIEUW , met Object.create , of op basis van de letterlijke (functies standaard om te functioneren .Prototype, cijfers naar nummer.Prototype, enz.). Het kan alleen worden gelezen met Object.getPrototypeof (SomeObject) . Er is nee andere manier om deze waarde in te stellen of te lezen.

Functies, naast het verborgen [[Prototype]] hebben ook een woning genaamd prototype , en dit is dit dat u toegang hebt en wijzigt, om geërfde eigenschappen en methoden voor de objecten die u maakt.


Hier is een voorbeeld:

ObjMaker = function() {this.a = 'first';};
// ObjMaker is just a function, there's nothing special about it that makes 
// it a constructor.
ObjMaker.prototype.b = 'second';
// like all functions, ObjMaker has an accessible prototype property that 
// we can alter. I just added a property called 'b' to it. Like 
// all objects, ObjMaker also has an inaccessible [[prototype]] property
// that we can't do anything with
obj1 = new ObjMaker();
// 3 things just happened.
// A new, empty object was created called obj1.  At first obj1 was the same
// as {}. The [[prototype]] property of obj1 was then set to the current
// object value of the ObjMaker.prototype (if ObjMaker.prototype is later
// assigned a new object value, obj1's [[prototype]] will not change, but you
// can alter the properties of ObjMaker.prototype to add to both the
// prototype and [[prototype]]). The ObjMaker function was executed, with
// obj1 in place of this... so obj1.a was set to 'first'.
obj1.a;
// returns 'first'
obj1.b;
// obj1 doesn't have a property called 'b', so JavaScript checks 
// its [[prototype]]. Its [[prototype]] is the same as ObjMaker.prototype
// ObjMaker.prototype has a property called 'b' with value 'second'
// returns 'second'

Het lijkt op klasse-overerving omdat nu alle objecten die u maakt met new ObjMaker(), ook de eigenschap ‘b’ lijken te hebben geërfd.

Als je zoiets als een subklasse wilt, doe je dit:

SubObjMaker = function () {};
SubObjMaker.prototype = new ObjMaker(); // note: this pattern is deprecated!
// Because we used 'new', the [[prototype]] property of SubObjMaker.prototype
// is now set to the object value of ObjMaker.prototype.
// The modern way to do this is with Object.create(), which was added in ECMAScript 5:
// SubObjMaker.prototype = Object.create(ObjMaker.prototype);
SubObjMaker.prototype.c = 'third';  
obj2 = new SubObjMaker();
// [[prototype]] property of obj2 is now set to SubObjMaker.prototype
// Remember that the [[prototype]] property of SubObjMaker.prototype
// is ObjMaker.prototype. So now obj2 has a prototype chain!
// obj2 ---> SubObjMaker.prototype ---> ObjMaker.prototype
obj2.c;
// returns 'third', from SubObjMaker.prototype
obj2.b;
// returns 'second', from ObjMaker.prototype
obj2.a;
// returns 'first', from SubObjMaker.prototype, because SubObjMaker.prototype 
// was created with the ObjMaker function, which assigned a for us

Ik heb een hoop onzin over dit onderwerp gelezen voordat ik uiteindelijk deze pagina, waar dit heel goed wordt uitgelegd met mooie diagrammen.


Antwoord 2, autoriteit 19%

Stel dat je deze functie hebt:

var Foo = function(){
  this.A = 1;
  this.B = 2;
};

Als je dit als een zelfstandige functie aanroept, zoals:

Foo();

Het uitvoeren van deze functie voegt twee eigenschappen toe aan het window-object (Aen B). Het voegt het toe aan het windowomdat windowhet object is dat de functie heeft aangeroepen als je het zo uitvoert, en thisin een functie is de object dat de functie heeft aangeroepen. In Javascript tenminste.

Noem het nu zo met new:

var bar = new Foo();

Wat er gebeurt als je newtoevoegt aan een functieaanroep, is dat er een nieuw object wordt gemaakt (alleen var bar = new Object()) en dat de thisin de functie verwijst naar het nieuwe Objectdat u zojuist hebt gemaakt, in plaats van naar het object dat de functie heeft aangeroepen. Dus baris nu een object met de eigenschappen Aen B. Elke functie kan een constructor zijn, het is alleen niet altijd logisch.


Antwoord 3, autoriteit 8%

Naast het antwoord van Daniel Howard, is dit wat newdoet (of in ieder geval lijkt te doen):

function New(func) {
    var res = {};
    if (func.prototype !== null) {
        res.__proto__ = func.prototype;
    }
    var ret = func.apply(res, Array.prototype.slice.call(arguments, 1));
    if ((typeof ret === "object" || typeof ret === "function") && ret !== null) {
        return ret;
    }
    return res;
}

Terwijl

var obj = New(A, 1, 2);

is gelijk aan

var obj = new A(1, 2);

4, Autoriteit 6%

voor beginners om het beter te begrijpen

Probeer de volgende code in de browserconsole.

function Foo() { 
    return this; 
}
var a = Foo();       //returns window object
var b = new Foo();   //returns empty object of foo
a instanceof Window;  // true
a instanceof Foo;     // false
b instanceof Window;  // false
b instanceof Foo;     // true

Nu kunt u de communautair wiki antwoorden : )


5, Autoriteit 2%

Dus het is waarschijnlijk niet om te creëren
gevallen van object

Het wordt daarvoor precies gebruikt. U definieert een functie-constructeur zoals SO:

function Person(name) {
    this.name = name;
}
var john = new Person('John');

Het extra voordeel dat Ecmascript heeft, is dat u kunt uitstrekken met de .prototypeonroerend goed, zodat we iets als …

kunnen doen

Person.prototype.getName = function() { return this.name; }

Alle objecten die uit deze constructor zijn gemaakt, hebben nu een getNamevanwege de prototype ketting waartoe ze toegang hebben.


6

JavaScript is een objectgeoriënteerde programmeertaal en wordt precies gebruikt voor het maken van gevallen. Het is gebaseerd op de prototype, in plaats van op basis van de klas, maar dat betekent niet dat het geen object-georiënteerd is.


7

SAMENVATTING:

De newTrefwoord wordt gebruikt in JavaScript om een ​​object uit een constructormunctie te maken. De newTrefwoord moet vóór de functie CONSTRUCTOR-functie worden geplaatst en zal de volgende dingen doen:

  1. Creëert een nieuw object
  2. Stelt het prototype van dit object in op de prototype-eigenschap van de constructorfunctie
  3. Bindt de thistrefwoord aan het nieuw gemaakte object en voert de constructor-functie
  4. uit

  5. Retourneert het nieuw gemaakte object

Voorbeeld:

function Dog (age) {
  this.age = age;
}
const doggie = new Dog(12);
console.log(doggie);
console.log(Object.getPrototypeOf(doggie) === Dog.prototype) // true

8

Er zijn al enkele zeer grote antwoorden, maar ik plaatwerk een nieuwe om mijn observatie te benadrukken op zaak III hieronder over wat er gebeurt wanneer u een expliciete retourverklaring hebt in een functie die u newING UP. Bekijk onderstaande gevallen:

Case I :

var Foo = function(){
  this.A = 1; 
  this.B = 2;
};
console.log(Foo()); //prints undefined
console.log(window.A); //prints 1

hierboven is een gewone zaak van het oproepen van de anonieme functie die wordt gewezen door Foo. Wanneer u deze functie noemt, wordt het undefinedaangeduid. Aangezien er geen expliciete retourverklaring is, wordt JavaScript-interpreter krachtig een return undefined;verklaring aan het einde van de functie. Hier is het venster het aanroepobject (contextueel this) die nieuwe Aen Beigenschappen krijgt.

Case II :

var Foo = function(){
  this.A = 1;
  this.B = 2;
};
var bar = new Foo();
console.log(bar()); //illegal isn't pointing to a function but an object
console.log(bar.A); //prints 1

Hier JavaScript-interpreter zien van de newsleutelwoord creëert een nieuw object dat fungeert als het aanroepobject (contextueel this) van anonieme functie die wordt gewezen door Foo. In dit geval AEN BWORDEN EIGENSCHAPPEN OP HET NIEUWE aangemaakte object (in plaats van vensterobject). Aangezien u geen expliciete retourverklaring heeft, zodat JavaScript-interpreter krachtig een retourverklaring inzet om het nieuwe object dat is gemaakt door het gebruik van newTrefwoord weer te geven.

Case III :

var Foo = function(){
  this.A = 1;
  this.B = 2;
  return {C:20,D:30}; 
};
var bar = new Foo();
console.log(bar.C);//prints 20
console.log(bar.A); //prints undefined. bar is not pointing to the object which got created due to new keyword.

Hier nogmaals JavaScript-interpreter die het newtrefwoord ziet, creëert een nieuw object dat fungeert als het aanroepobject (contextuele this) van een anonieme functie waarnaar wordt verwezen door Foo. Nogmaals, Aen Bworden eigenschappen op het nieuw gemaakte object. Maar deze keer heb je een expliciete return-instructie, zodat de JavaScript-interpreter nietzelf iets doet.

Het ding om op te merken in het geval IIIis dat het object dat werd gemaakt vanwege het newtrefwoord, van uw radar is verdwenen. barverwijst eigenlijk naar een heel ander object dat niet het object is dat de JavaScript-interpreter heeft gemaakt vanwege het new-zoekwoord.

Een citaat van David Flanagan uit JavaScripit: The Definitive Guide (6e editie), Ch. 4, Pagina # 62:

Wanneer een expressie voor het maken van een object wordt geëvalueerd, eerst JavaScript
maakt een nieuw leeg object, net als degene die door het object is gemaakt
initialisatie {}. Vervolgens roept het de gespecificeerde functie op met de
opgegeven argumenten, waarbij het nieuwe object wordt doorgegeven als de waarde van de this
trefwoord. De functie kan dit dan gebruiken om de eigenschappen te initialiseren
van het nieuw gemaakte object. Functies geschreven voor gebruik als constructors
retourneer geen waarde, en de waarde van de expressie voor het maken van objecten
is het nieuw gemaakte en geïnitialiseerde object. Als een constructeur dat doet
retourneer een objectwaarde, die waarde wordt de waarde van het object
creatie-expressie en het nieuw gemaakte object wordt verwijderd.

Aanvullende informatie

De functies die in het codefragment van bovenstaande gevallen worden gebruikt, hebben speciale namen in de JS-wereld, zoals hieronder:

Case I en II– Constructorfunctie

Case III– Fabrieksfunctie. Fabrieksfuncties moeten nietworden gebruikt met newtrefwoord, wat ik heb gedaan om het concept in de huidige thread uit te leggen.

Je kunt het verschil tussen beide lezen in dezethread.


Antwoord 9

Javascript is een dynamische programmeertaal die het objectgeoriënteerde programmeerparadigma ondersteunt en wordt gebruikt voor het maken van nieuwe exemplaren van objecten.

Klassen zijn niet nodig voor objecten – Javascript is een prototype-gebaseerdetaal.


Antwoord 10

Het newsleutelwoord verandert de context waaronder de functie wordt uitgevoerd en retourneert een verwijzing naar die context.

Als u het trefwoord newniet gebruikt, is de context waaronder de functie Vehicle()draait dezelfde context van waaruit u het Vehiclefunctie. Het trefwoord thisverwijst naar dezelfde context. Wanneer u new Vehicle()gebruikt, wordt er een nieuwe context gemaakt, dus het trefwoord thisin de functie verwijst naar de nieuwe context. Wat je ervoor terugkrijgt is de nieuw gecreëerde context.


Antwoord 11

soms is code makkelijker dan woorden:

var func1 = function (x) { this.x = x; }                    // used with 'new' only
var func2 = function (x) { var z={}; z.x = x; return z; }   // used both ways
func1.prototype.y = 11;
func2.prototype.y = 12;
A1 = new func1(1);      // has A1.x  AND  A1.y
A2 =     func1(1);      // undefined ('this' refers to 'window')
B1 = new func2(2);      // has B1.x  ONLY
B2 =     func2(2);      // has B2.x  ONLY

Voor mij, zolang ik geen prototype, gebruik ik stijl van func2 omdat het me een beetje meer flexibiliteit geeft binnen en buiten de functie.


12

Het newtrefwoord is voor het maken van nieuwe objectinstanties. En ja, javascript is een dynamische programmeertaal, die het objectgeoriënteerde programmeerparadigma ondersteunt. De conventie over de naamgeving van objecten is: gebruik altijd hoofdletters voor objecten die door het nieuwe trefwoord moeten worden geïnstantieerd.

obj = new Element();

Antwoord 13

Het sleutelwoord newmaakt instanties van objecten met behulp van functies als constructor. Bijvoorbeeld:

var Foo = function() {};
Foo.prototype.bar = 'bar';
var foo = new Foo();
foo instanceof Foo; // true

Instances erven van het prototypevan de constructorfunctie. Dus gezien het bovenstaande voorbeeld…

foo.bar; // 'bar'

Antwoord 14

Javascript is geen objectgeoriënteerde programmeertaal (OOP), daarom is het LOOK UP-proces
in javascript werken met behulp van ‘DELEGATIEPROCES’ook bekend als prototype-delegatie of prototypische overerving.

Als u probeert de waarde van een eigenschap te halen uit een object dat het niet heeft, wordt de
JavaScript-engine kijkt naar het prototype van het object (en het prototype, stap voor stap hoger)
het is een prototypeketen totdat de keten eindigt op null, wat Object.prototype == nullis (Standard Object Prototype).
Als de eigenschap of methode op dit moment niet is gedefinieerd, wordt undefinedgeretourneerd.

Dus met het newtrefwoord zijn enkele taken die handmatig zijn uitgevoerd, bijvoorbeeld

  1. Handmatige objectcreatie, bijv. newObj.
  2. Verborgen binding creëren met behulp van proto(ook bekend als: dunder proto) in JS spec [[prototype]](dwz proto)
  3. verwijzen naar en eigenschappen toewijzen aan newObj
  4. teruggave van newObjobject.

Alles wordt handmatig gedaan.

function CreateObj(value1, value2) {
  const newObj = {};
  newObj.property1 = value1;
  newObj.property2 = value2;
  return newObj;
}
var obj = CreateObj(10,20);
obj.__proto__ === Object.prototype;              // true
Object.getPrototypeOf(obj) === Object.prototype // true

Javascript-zoekwoord newhelpt dit proces te automatiseren:

  1. nieuwe letterlijke objectwaarde wordt gemaakt, geïdentificeerd door this:{}
  2. verwijzen naar en eigenschappen toewijzen aan this
  3. Verborgen binding Creatie [[prototype]] (d.w.z. proto)naar Function.prototype gedeelde ruimte.
  4. impliciete terugkeer van thisobject {}
function CreateObj(value1, value2) {
  this.property1 = value1;
  this.property2 = value2;
}
var obj = new CreateObj(10,20);
obj.__proto__ === CreateObj.prototype             // true
Object.getPrototypeOf(obj) == CreateObj.prototype // true

Constructeurfunctie aanroepen zonder het nieuwe trefwoord:

=> this: Window

function CreateObj(value1, value2) {
  var isWindowObj = this === window;
  console.log("Is Pointing to Window Object", isWindowObj);
  this.property1 = value1;
  this.property2 = value2;
}
var obj = new CreateObj(10,20); // Is Pointing to Window Object false
var obj = CreateObj(10,20); // Is Pointing to Window Object true
window.property1; // 10
window.property2; // 20

Antwoord 15

Nou ja, JavaScript kan per si sterk verschillen van platform tot platform, aangezien het altijd een implementatie is van de originele specificatie EcmaScript.

In elk geval, onafhankelijk van de implementatie, zullen alle JavaScript-implementaties die het EcmaScript-specificatierecht volgen, u een objectgeoriënteerde taal geven. Volgens de ES-norm:

ECMAScript is een objectgeoriënteerde programmeertaal voor:
berekeningen uitvoeren en computationele objecten manipuleren
binnen een hostomgeving.

Dus nu we het erover eens zijn dat JavaScript een implementatie is van EcmaScript en daarom een objectgeoriënteerde taal is. De definitie van de new-bewerking in elke objectgeoriënteerde taal, zegt dat een dergelijk sleutelwoord wordt gebruikt om een objectinstantie te maken van een klasse van een bepaald type (inclusief anonieme typen, in gevallen zoals C#).

In EcmaScript gebruiken we geen klassen, zoals je kunt lezen in de specificaties:

ECMAScript gebruikt geen klassen zoals die in C++, Smalltalk of Java. In plaats daarvan kunnen objecten op verschillende manieren worden gemaakt, waaronder via
een letterlijke notatie of via constructors die objecten maken en vervolgens code uitvoeren die ze allemaal of een deel ervan initialiseert door initiële
waarden aan hun eigenschappen. Elke constructor is een functie met a
eigenschap met de naam ―
prototype ‖ dat wordt gebruikt om op prototypes gebaseerde overerving en gedeelde eigenschappen te implementeren. Objecten zijn gemaakt door
constructors gebruiken in nieuwe expressies; bijvoorbeeld nieuwe
Date(2009,11) maakt een nieuw Date-object aan. Een constructor aanroepen
zonder nieuw te gebruiken heeft consequenties die afhankelijk zijn van de constructor.
Datum () produceert bijvoorbeeld een reeksvertegenwoordiging van de
huidige datum en tijd in plaats van een object.

Other episodes