Vraag Wat is het 'nieuwe' zoekwoord in JavaScript?


De new keyword in JavaScript kan nogal verwarrend zijn wanneer het voor het eerst wordt gevonden, omdat mensen de neiging hebben om te denken dat JavaScript geen object-georiënteerde programmeertaal is.

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

1555
2017-10-29 21:32


oorsprong


antwoorden:


Het doet 5 dingen:

  1. Het maakt een nieuw object. Het type van dit object is eenvoudig voorwerp.
  2. Het stelt het interne, ontoegankelijke, [[prototype]] (d.w.z. __proto__) eigenschap om de externe, toegankelijke, prototype object (elk functieobject heeft automatisch een prototype eigendom).
  3. Het maakt de this variabele punt naar het nieuw gemaakte object.
  4. Het voert de constructorfunctie uit, telkens wanneer het nieuw gecreëerde object wordt gebruikt this is genoemd.
  5. Het geeft het nieuw gemaakte object als resultaat, tenzij de constructorfunctie een niet-object retourneertnull objectreferentie. In dit geval wordt die objectreferentie in plaats daarvan geretourneerd.

Notitie: constructorfunctie verwijst naar de functie na de new trefwoord, zoals in

new ConstructorFunction(arg1, arg2)

Als dit eenmaal is gebeurd, controleert het script het object als een ongedefinieerde eigenschap van het nieuwe object wordt aangevraagd [[prototype]] object in plaats daarvan. Dit is hoe u iets kunt krijgen dat lijkt op traditionele klasse-overerving in JavaScript.

Het moeilijkste hieraan is punt 2. Elk object (inclusief functies) heeft dit interne kenmerk genaamd [[prototype]]. Het kan enkel en alleen worden ingesteld op het tijdstip waarop het object wordt gemaakt, met of nieuwe, met Object.create, of op basis van het letterlijke (functies standaard naar Function.prototype, getallen naar Number.prototype, etc.). Het kan alleen worden gelezen met Object.getPrototypeOf (someObject). Er bestaat Nee andere manier om deze waarde in te stellen of te lezen.

Functies, naast het verborgene [[prototype]] eigendom, heeft ook een eigenschap genaamd prototype, en dit is het dat u kunt openen en wijzigen om overerfde eigenschappen en methoden te bieden 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 is net als klasse-overerving, omdat nu alle objecten die u gebruikt new ObjMaker() lijkt ook de eigenschap 'b' geërfd te hebben.

Als u iets als een subklasse wilt, dan doet u 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 rotzooi over dit onderwerp gelezen voordat ik eindelijk vond deze pagina, waar dit heel goed wordt uitgelegd met mooie diagrammen.


1958
2017-10-29 22:22



Stel dat je deze functie hebt:

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

Als je dit een zelfstandige functie noemt zoals:

Foo();

Als u deze functie uitvoert, voegt u twee eigenschappen toe aan de window voorwerp (A en B). Het voegt het toe aan de window omdat window is het object dat de functie heeft aangeroepen wanneer je het zo uitvoert, en this in een functie is het object dat de functie heeft aangeroepen. In Javascript tenminste.

Nu, noem het zo met new:

var bar = new Foo();

Wat gebeurt er als je toevoegt new naar een functieaanroep is dat een nieuw object wordt gemaakt (alleen var bar = new Object()) en dat het this binnen de functie wijst naar de nieuwe Object u zojuist hebt gemaakt, in plaats van naar het object dat de functie heeft aangeroepen. Zo bar is nu een object met de eigenschappen A en B. Elke functie kan een constructeur zijn, het is gewoon niet altijd logisch.


359
2018-06-20 23:46



In aanvulling op Daniel Howard's antwoord, hier is wat new doet (of lijkt het tenminste 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);

146
2018-05-27 09:23



Voor beginners om het beter te begrijpen

probeer de volgende code in de browser console.

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 kun je het community wiki-antwoord lezen :)


85
2017-10-29 21:34



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

Het is precies daarvoor gebruikt. U definieert een functieconstructor zoals:

function Person(name) {
    this.name = name;
}

var john = new Person('John');

Het extra voordeel dat ECMAScript heeft, is echter dat u kunt uitbreiden met de .prototype eigendom, zodat we iets als ... kunnen doen

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

Alle objecten gemaakt van deze constructor hebben nu een getName vanwege de prototypeketen waartoe ze toegang hebben.


33
2017-10-29 21:36



JavaScript is een object-georiënteerde programmeertaal en het is precies gebruikt voor het maken van instanties. Het is gebaseerd op prototypes in plaats van op klassen, maar dat betekent niet dat het niet objectgeoriënteerd is.


26
2017-10-29 21:37



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

Klassen zijn niet nodig voor objecten - Javascript is a prototype gebaseerd taal.


13
2018-05-16 07:21



soms is code eenvoudiger 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 maak, gebruik ik stijl van func2 omdat het me wat meer flexibiliteit geeft binnen en buiten de functie.


3
2017-10-29 21:38