Maakt een functie-aangifte een object aan in Javascript?

Functieconstructeurs kunnen objecten maken in JavaScript maar Ik heb een meer fundamentele vraag.

Een duidelijke functie in Javascript declareren met behulp van een "functieverklaring" zoals

function Foo() 
{
  this.prop1 = 20;
  //some code
}

Maakt dit intern een object in JavaScript heap aan met de aanwijzer als abc en prop1 als 20?

Of is het dat de objecten alleen worden gemaakt als de functieconstructor wordt aangeroepen net zoals

var a = new Foo() //This definately creates a new object
1

4 antwoord

In JavaScript zijn alle functies objecten.

Je kunt dit soort dingen doen:

function foo() {
    return true;
}

foo.greeting = "hello";
foo.tone = "mean";
foo.talk = function() {
    alert(foo.greeting);
}

foo.talk();

Een functieobject heeft dezelfde mogelijkheden als een normaal javascript-object, maar het kan ook enkele aanvullende dingen doen, zoals worden gebruikt als een constructor en het heeft een paar ingebouwde eigenschappen. Zie de MDN-pagina over functieobjecten voor een beschrijving van de andere eigenschappen/methoden die het heeft.

3
toegevoegd
Gegeven een variabele hoe kunnen we zien of het een functieobject of een normaal object is met behulp van javascript-code?
toegevoegd de auteur seahorse, de bron
@seahorse: met typeof . Het zal "function" voor functies teruggeven.
toegevoegd de auteur Felix Kling, de bron
U kunt ook myFunction instanceof Function of myFunction.constructor == Function
toegevoegd de auteur Brian Nickel, de bron

De functiedeclaratie maakt alleen functieobject Foo aan, maar roept niet de functie aan of maakt er een instantie van.

Een exemplaar wordt alleen gemaakt wanneer u de functie daadwerkelijk met nieuw aanroept en tot die tijd bestaat de eigenschap die u aan this toekent, nergens.

Het kan ook heel goed zijn dat Foo nooit wordt genoemd als een constructorfunctie. Alleen al door naar een functie te kijken, weet je niet zeker of een functie wordt gebruikt als een constructorfunctie of niet.

2
toegevoegd
Wat is het verschil tussen een functieobject en een normaal object in javascript?
toegevoegd de auteur seahorse, de bron
Alles in JavaScript is een object. Intern zijn functies dus ook objecten, maar met speciale eigenschappen (ze zijn opvraagbaar). "Normale" objecten zijn niet opvraagbaar.
toegevoegd de auteur Felix Kling, de bron
Het is belangrijk om te weten dat, hoewel alles een -object is, niet alles een object is. true is geen Object, terwijl nieuwe Boolean (true) is. Tekenreeksen, booleans en getallen worden automatisch verwerkt om bestaande eigenschappen te verwerken, maar nieuwe eigenschappen die aan primatieven zijn toegewezen, worden onmiddellijk weggegooid.
toegevoegd de auteur Brian Nickel, de bron

Laten we de uitvoering regel voor regel doorlopen, regel 8 toevoegen voor een beter begrip:

/* 1 */ function Foo() 
/* 2 */ {
/* 3 */   this.prop1 = 20;
/* 4 */   //some code
/* 5 */ }
/* 6 */ 
/* 7 */ var a = new Foo()
/* 8 */ var b = Foo()

Regel 1 wordt uitgevoerd, de heap bevat nu één element, een functieobject met de naam Foo . Op dit moment is Foo niet uitgevoerd. Regels 2 t/m 5 worden op dit moment niet uitgevoerd, maar worden gebruikt als de body van Foo. Omdat Foo niet is aangeroepen, is regel 3 niet aangeroepen voor een object, dus niets heeft een prop1 .

Regel 7 wordt uitgevoerd, de interpreter doet verschillende dingen:

  1. Het voegt een nieuw object toe aan de heap.
  2. Het geeft dit object de prototypeketen van Foo . Dit doet niets bijzonders in het geval van Foo omdat we niets hebben toegewezen aan het prototype van Foo , maar Foo erft van Object , dus het object heeft nu methoden zoals hasOwnProperty en toString .
  3. De interpreter roept Foo door het nieuw gemaakte object door te geven als this .
  4. Regel 3 wordt uitgevoerd, waarbij 20 de eigenschap met de naam prop1 wordt toegewezen. Of dit een nieuw object in de fysieke heap maakt of als het wordt toegewezen aan een primitieve sectie van het object, hangt er echt van af hoe de interpretator alles optimaliseert. Ik weet zeker dat V8 het toevoegen van een object aan de heap vermijdt.
  5. Het nieuwe object wordt toegewezen aan a in het variabele bereik van a .

In feite voegt het maken van een functie de functie loader toe aan de heap (of mogelijk stack afhankelijk van het bereik en optimalisaties) en het uitvoeren van nieuwe Foo voegt een nieuw object toe aan de stapel.

Maar wat als we nieuw niet gebruiken?

Kijk voor het plezier naar het andere gedrag wanneer we new niet gebruiken. Wanneer regel 8 wordt uitgevoerd, omdat we new niet aanroepen, voeren we een normale functieaanroep uit en maken we geen nieuw object. Het volgende gebeurt:

  1. We call Foo on line one. Since we aren't in strict mode, this is assigned to the global window object.
  2. Line 3 executes, assigning window.prop1 = 20.
  3. The function returns undefined.
  4. b is set to undefined.
2
toegevoegd

Javascript is een beetje verwarrend omdat een functie zowel een normale functie zonder/standaardcontext is, maar gepaard met nieuw maakt het een nieuw object. Zo

function Foo() {
    this.prop1 = 20;
}

console.log( typeof(Foo) ); //-> 'function' 

maakt een object met de naam Foo dat van het type function is. Nu kunnen we onze functieobjecten nemen en nieuwe objecten maken die aan de huidige stapel worden toegevoegd:

var bar = new Foo();
console.log( typeof(bar) );//-> 'object' with a pointer named prop1 to 20

Nu hebben we 2 objecten, Foo en bar die verwijzen naar een object dat is gemaakt met Foo als een constructor met nieuw. Dus nieuw is eigenlijk magisch en is een van de drie manieren om objecten in Javascript te maken. De drie manieren zijn:

var object = {};//Creates an object using object literal notation
new Foo();//Creates an object with built in 'new'
Object.create(null);//new ECMA5 notation that avoid using new
0
toegevoegd