statische variabelen in Javascript

Hoe kan ik statische variabelen maken in JavaScript?


1, Autoriteit 100%

Als u afkomstig is van een op klassen gebaseerde, statisch getypte objectgerichte taal (zoals Java, C++ of C #) , neem ik aan dat u probeert een variabele of methode te maken die is gekoppeld aan een “type “Maar niet op een instantie.

Een voorbeeld met behulp van een “klassieke” benadering, met constructor-functies kan u misschien helpen om de concepten van Basic OO JavaScript te vangen:

function MyClass () { // constructor function
  var privateVariable = "foo";  // Private variable 
  this.publicVariable = "bar";  // Public variable 
  this.privilegedMethod = function () {  // Public Method
    alert(privateVariable);
  };
}
// Instance method will be available to all instances but only load once in memory 
MyClass.prototype.publicMethod = function () {    
  alert(this.publicVariable);
};
// Static variable shared by all instances
MyClass.staticProperty = "baz";
var myInstance = new MyClass();

staticPropertyis gedefinieerd in het MyClass-object (dat een functie is) en heeft niets te maken met de gecreëerde instanties, JavaScript behandelt functioneert als Eersteklas objecten , dus een object, kunt u eigenschappen toewijzen aan een functie.

Update: ES6 introduceerde de mogelijkheid om Verklaar klassen via de classtrefwoord. Het is syntaxisuiker over het bestaande overerving op prototype.

Het statictrefwoord stelt u in staat om eenvoudig statische eigenschappen of methoden in een klasse te definiëren.

Laten we het bovenstaande voorbeeld bekijken, geïmplementeerd met ES6-klassen:

class MyClass {
  // class constructor, equivalent to
  // the function body of a constructor
  constructor() {
    const privateVariable = 'private value'; // Private variable at the constructor scope
    this.publicVariable = 'public value'; // Public property
    this.privilegedMethod = function() {
      // Public Method with access to the constructor scope variables
      console.log(privateVariable);
    };
  }
  // Prototype methods:
  publicMethod() {
    console.log(this.publicVariable);
  }
  // Static properties shared by all instances
  static staticProperty = 'static value';
  static staticMethod() {
    console.log(this.staticProperty);
  }
}
// We can add properties to the class prototype
MyClass.prototype.additionalMethod = function() {
  console.log(this.publicVariable);
};
var myInstance = new MyClass();
myInstance.publicMethod();       // "public value"
myInstance.additionalMethod(); // "public value"
myInstance.privilegedMethod(); // "private value"
MyClass.staticMethod();             // "static value"

Antwoord 2, autoriteit 60%

Je zou kunnen profiteren van het feit dat JS-functies ook objecten zijn — wat betekent dat ze eigenschappen kunnen hebben.

Citeren bijvoorbeeld het voorbeeld op het (nu verdwenen) artikel statische variabelen in Javascript :

function countMyself() {
    // Check to see if the counter has been initialized
    if ( typeof countMyself.counter == 'undefined' ) {
        // It has not... perform the initialization
        countMyself.counter = 0;
    }
    // Do something stupid to indicate the value
    alert(++countMyself.counter);
}

Als u die functie meerdere keer oproept, ziet u dat de teller wordt verhoogd.

En dit is waarschijnlijk een veel betere oplossing dan het poluteren van de wereldwijde naamruimte met een globale variabele.

En hier is een andere mogelijke oplossing, op basis van een sluiting: Trick om statische variabelen in Javascript te gebruiken :

var uniqueID = (function() {
   var id = 0; // This is the private persistent value
   // The outer function returns a nested function that has access
   // to the persistent value.  It is this nested function we're storing
   // in the variable uniqueID above.
   return function() { return id++; };  // Return and increment
})(); // Invoke the outer function after defining it.

die je hetzelfde soort resultaat krijgt – behalve, deze keer wordt de verhogende waarde geretourneerd, in plaats van weergegeven.


3, Autoriteit 11%

U doet het via een iife (onmiddellijk opgeroepen functies uitdrukking):

var incr = (function () {
    var i = 1;
    return function () {
        return i++;
    }
})();
incr(); // returns 1
incr(); // returns 2

4, Autoriteit 4%

U kunt argumenten gebruiken. Callee om “Statische” variabelen op te slaan (dit is ook handig in anonieme functie):

function () {
  arguments.callee.myStaticVar = arguments.callee.myStaticVar || 1;
  arguments.callee.myStaticVar++;
  alert(arguments.callee.myStaticVar);
}

5, Autoriteit 3%

Bijgewerkt antwoord:

in ecmascript 6 , kunt u statische functies maken met behulp van de statictrefwoord:

class Foo {
  static bar() {return 'I am static.'}
}
//`bar` is a property of the class
Foo.bar() // returns 'I am static.'
//`bar` is not a property of instances of the class
var foo = new Foo()
foo.bar() //-> throws TypeError

ES6-lessen introduceren geen nieuwe semantiek voor statica. Je kunt hetzelfde doen in ES5 als deze:

//constructor
var Foo = function() {}
Foo.bar = function() {
    return 'I am static.'
}
Foo.bar() // returns 'I am static.'
var foo = new Foo()
foo.bar() // throws TypeError

U kunt toewijzen aan een eigenschap van Fooomdat in JavaScript-functies objecten zijn.


6, Autoriteit 3%

function Person(){
  if(Person.count == undefined){
    Person.count = 1;
  }
  else{
    Person.count ++;
  }
  console.log(Person.count);
}
var p1 = new Person();
var p2 = new Person();
var p3 = new Person();

7, Autoriteit 2%

Het volgende voorbeeld en uitleg komen uit het boek Professional JavaScript voor webontwikkelaars 2e editie door Nicholas Zakas. Dit is het antwoord dat ik op zoek was, dus ik dacht dat het nuttig zou zijn om het hier toe te voegen.

(function () {
    var name = '';
    Person = function (value) {
        name = value;
    };
    Person.prototype.getName = function () {
        return name;
    };
    Person.prototype.setName = function (value) {
        name = value;
    };
}());
var person1 = new Person('Nate');
console.log(person1.getName()); // Nate
person1.setName('James');
console.log(person1.getName()); // James
person1.name = 'Mark';
console.log(person1.name); // Mark
console.log(person1.getName()); // James
var person2 = new Person('Danielle');
console.log(person1.getName()); // Danielle
console.log(person2.getName()); // Danielle

De PersonConstructor In dit voorbeeld heeft toegang tot de particuliere variabele naam, net als de getName()en setName()-methoden. Met behulp van dit patroon wordt de naam variabele statisch en wordt onder alle gevallen gebruikt. Dit betekent bellen met setName()AAN ONE INSTRUME BEPALEN alle andere gevallen. Bellen setName()OF EEN NIEUWE PersonINSTELLING Stelt de naam Variabel in op een nieuwe waarde. Dit zorgt ervoor dat alle instanties dezelfde waarde retourneren.


8, Autoriteit 2%

Als u de nieuwe klasse syntaxis Dan kunt u nu het volgende doen:

   class MyClass {
      static get myStaticVariable() {
        return "some static variable";
      }
    }
    console.log(MyClass.myStaticVariable);
    aMyClass = new MyClass();
    console.log(aMyClass.myStaticVariable, "is undefined");

Antwoord 9

Als u statische variabelen wilt declareren voor het maken van constanten in uw toepassing, vond ik de volgende benadering de meest simplistische benadering

ColorConstants = (function()
{
    var obj = {};
    obj.RED = 'red';
    obj.GREEN = 'green';
    obj.BLUE = 'blue';
    obj.ALL = [obj.RED, obj.GREEN, obj.BLUE];
    return obj;
})();
//Example usage.
var redColor = ColorConstants.RED;

Antwoord 10

Over de classgeïntroduceerd door ECMAScript 2015. De andere antwoorden zijn niet helemaal duidelijk.

Hier is een voorbeeld dat laat zien hoe u een statische var staticVarmaakt met de ClassName.varsynthax:

class MyClass {
    constructor(val) {
        this.instanceVar = val;
        MyClass.staticVar = 10;
    }
}
var class1 = new MyClass(1);
console.log(class1.instanceVar);      // 1
console.log(class1.constructor.staticVar); // 10
// New instance of MyClass with another value
var class2 = new MyClass(3);
console.log(class1.instanceVar);      // 1
console.log(class2.instanceVar);      // 3

Om toegang te krijgen tot de statische variabele, gebruiken we de .constructoreigenschap die een verwijzing retourneert naar de functie Object Constructor die de klas heeft gemaakt.
We kunnen het op de twee gecreëerde instanties noemen:

MyClass.staticVar = 11;
console.log(class1.constructor.staticVar); // 11
console.log(class2.constructor.staticVar); // 11 <-- yes it's static! :)
MyClass.staticVar = 12;
console.log(class1.constructor.staticVar); // 12
console.log(class2.constructor.staticVar); // 12

11

Er zijn andere soortgelijke antwoorden, maar geen van hen had me helemaal in beroep. Dit is waar ik eindigde mee:

var nextCounter = (function () {
  var counter = 0;
  return function() {
    var temp = counter;
    counter += 1;
    return temp;
  };
})();

12

Naast de rest is er momenteel een concept (fase-2 voorstel ) aan ECMA-voorstellen die u introduceert staticPublic Velden in de lessen . (Particuliere velden werden overwogen )

Gebruik het voorbeeld van het voorstel, de voorgestelde staticSyntaxis ziet er als volgt uit:

class CustomDate {
  // ...
  static epoch = new CustomDate(0);
}

en gelijkwaardig zijn aan het volgende dat anderen hebben gemarkeerd:

class CustomDate {
  // ...
}
CustomDate.epoch = new CustomDate(0);

Je hebt er dan toegang toe via CustomDate.epoch.

Je kunt het nieuwe voorstel volgen in proposal-static-class-features.


Momenteel ondersteunt babel deze functie met de plug-in transform class propertiesdie je kunt gebruiken. Bovendien, hoewel nog in uitvoering, V8implementeert het.


Antwoord 13

U kunt hieronder een statische variabele in JavaScript maken. Hier is countde statische variabele.

var Person = function(name) {
  this.name = name;
  // first time Person.count is undefined, so it is initialized with 1
  // next time the function is called, the value of count is incremented by 1
  Person.count = Person.count ? Person.count + 1 : 1;
}
var p1 = new Person('User p1');
console.log(p1.constructor.count);   // prints 1
var p2 = new Person('User p2');
console.log(p2.constructor.count);   // prints 2

U kunt waarden toewijzen aan de statische variabele met behulp van de functie Personof een van de volgende instanties:

// set static variable using instance of Person
p1.constructor.count = 10;         // this change is seen in all the instances of Person
console.log(p2.constructor.count); // prints 10
// set static variable using Person
Person.count = 20;
console.log(p1.constructor.count); // prints 20

Antwoord 14

Als je een globale statische variabele wilt maken:

var my_id = 123;

Vervang de variabele door het onderstaande:

Object.defineProperty(window, 'my_id', {
    get: function() {
            return 123;
        },
    configurable : false,
    enumerable : false
});

Antwoord 15

Er zijn 4 manieren om functie-lokale statische variabelen in Javascript te emuleren.

Methode 1: Functieobjecteigenschappen gebruiken(ondersteund in oude browsers)

function someFunc1(){
    if( !('staticVar' in someFunc1) )
        someFunc1.staticVar = 0 ;
    alert(++someFunc1.staticVar) ;
}
someFunc1() ; //prints 1
someFunc1() ; //prints 2
someFunc1() ; //prints 3

Methode 2: Een sluiting gebruiken, variant 1(ondersteund in oude browsers)

var someFunc2 = (function(){
    var staticVar = 0 ;
    return function(){
        alert(++staticVar) ;
    }
})()
someFunc2() ; //prints 1
someFunc2() ; //prints 2
someFunc2() ; //prints 3

Methode 3: Een sluiting gebruiken, variant 2(ook ondersteund in oude browsers)

var someFunc3 ;
with({staticVar:0})
    var someFunc3 = function(){
        alert(++staticVar) ;
    }
someFunc3() ; //prints 1
someFunc3() ; //prints 2
someFunc3() ; //prints 3

Methode 4: Een sluiting gebruiken, variant 3(vereist ondersteuning voor EcmaScript 2015)

{
    let staticVar = 0 ;
    function someFunc4(){
        alert(++staticVar) ;
    }
}
someFunc4() ; //prints 1
someFunc4() ; //prints 2
someFunc4() ; //prints 3

Antwoord 16

Het dichtst in de buurt van een statische variabele in JavaScript is een globale variabele – dit is gewoon een variabele gedeclareerd buiten het bereik van een functie of object letterlijk:

var thisIsGlobal = 1;
function foo() {
    var thisIsNot = 2;
}

Het andere dat u zou kunnen doen, is globale variabelen in een object letterlijk als volgt op te slaan:

var foo = { bar : 1 }

En open dan de variabelen als volgt: foo.bar.


Antwoord 17

Om alle klassenconcepten hier samen te vatten, test u dit:

var Test = function() {
  // "super private" variable, accessible only here in constructor. There are no real private variables
  //if as 'private' we intend variables accessible only by the class that defines the member and NOT by child classes
  var test_var = "super private";
  //the only way to access the "super private" test_var is from here
  this.privileged = function(){
    console.log(test_var);
  }();
  Test.test_var = 'protected';//protected variable: accessible only form inherited methods (prototype) AND child/inherited classes
  this.init();
};//end constructor
Test.test_var = "static";//static variable: accessible everywhere (I mean, even out of prototype, see domready below)
Test.prototype = {
 init:function(){
   console.log('in',Test.test_var);
 }
};//end prototype/class
//for example:
$(document).ready(function() {
 console.log('out',Test.test_var);
 var Jake = function(){}
 Jake.prototype = new Test();
 Jake.prototype.test = function(){
   console.log('jake', Test.test_var);
 }
 var jake = new Jake();
 jake.test();//output: "protected"
});//end domready

Nou, een andere manier om best practices op dit gebied te bekijken, is door te kijken hoe coffeescript deze concepten vertaalt.

#this is coffeescript
class Test
 #static
 @prop = "static"
 #instance
 constructor:(prop) ->
   @prop = prop
   console.log(@prop)
 t = new Test('inst_prop');
 console.log(Test.prop);
//this is how the above is translated in plain js by the CS compiler
  Test = (function() {
    Test.prop = "static";
    function Test(prop) {
     this.prop = prop;
     console.log(this.prop);
    }
    return Test;
  })();
  t = new Test('inst_prop');
  console.log(Test.prop);

Antwoord 18

Er is een andere benadering die mijn vereisten oploste na het doorbladeren van deze thread. Het hangt af van wat u precies wilt bereiken met een “statische variabele”.

Met de globale eigenschap sessionStorage of localStorage kunnen gegevens respectievelijk worden opgeslagen voor de duur van de sessie, of voor een onbepaalde langere periode totdat ze expliciet worden gewist. Hierdoor kunnen gegevens worden gedeeld tussen alle vensters, frames, tabbladen, pop-ups enz. van uw pagina/app en is het veel krachtiger dan een simpele “statische/algemene variabele” in één codesegment.

Het vermijdt alle rompslomp met de omvang, levensduur, semantiek, dynamiek enz. van globale variabelen op het hoogste niveau, zoals Window.myglobal. Ik weet niet hoe efficiënt het is, maar dat is niet belangrijk voor bescheiden hoeveelheden gegevens die tegen bescheiden tarieven worden benaderd.

Gemakkelijk toegankelijk als “sessionstorage.mydata = alles” en op dezelfde manier opgehaald. Zien
“JavaScript: de definitieve gids, zesde editie”, David Flanagan, ISBN: 978-0-596-805552-4, hoofdstuk 20, sectie 20.1. Dit is gemakkelijk te downloaden als een PDF door een eenvoudige zoekopdracht, of in het abonnement van O’REIlY Safaribooks (zijn gewicht in goud waard).


19

In JavaScript-variabelen zijn statisch standaard. Voorbeeld :

var x = 0;
function draw() {
    alert(x); //
    x+=1;
}
setInterval(draw, 1000);

De waarde van X wordt verhoogd door 1 elke 1000 milliseconden
Het drukt 1,2,3 zo weer af


20

Functie / klassen kunnen alleen enkele constructor voor zijn objectscope.
Function Hoisting, declarations & expressions

  • Functies gemaakt met de functie-constructor maken geen sluitingen aan hun creatiecontexten; Ze worden altijd gemaakt in de wereldwijde reikwijdte.

     var functionClass = function ( ) {
            var currentClass = Shape;
            _inherits(currentClass, superClass);
            function functionClass() { superClass.call(this); // Linking with SuperClass Constructor.
                // Instance Variables list.
                this.id = id;   return this;
            }
        }(SuperClass)
    

sluitingen – sluitingen van sluiting zijn functie met bewaardegegevens.

  • De kopieën van elke sluiting worden gemaakt naar een functie met hun eigen vrije waarden of verwijzingen. Telkens wanneer u een functie binnen een andere functie gebruikt, wordt een sluiting gebruikt.
  • Een afsluiting in JavaScript is als het bijhouden van een kopie van alle lokale variabelen van de bovenliggende functie door de innerFunctions.

     function closureFun( args ) {
            // Local variable that ends up within closure
            var num = args;
            num++;
            return function() { console.log(num); }
        }
        var closure1 = closureFun( 5 );
        var closure2 = closureFun( 777 );
        closure1(); // 5
        closure2(); // 777
        closure2(); // 778
        closure1(); // 6
    

ES5-functieklassen: gebruikt Object.defineProperty ( O, P, attributen )

De Object.defineProperty()methode definieert een nieuwe eigenschap direct op een object, of wijzigt een bestaande eigenschap op een object, en retourneert het object.

Een aantal methoden gemaakt met behulp van , zodat iedereen de functieklassen gemakkelijk kan begrijpen.

'use strict';
var Shape = function ( superClass ) {
    var currentClass = Shape;
    _inherits(currentClass, superClass); // Prototype Chain - Extends
    function Shape(id) { superClass.call(this); // Linking with SuperClass Constructor.
        // Instance Variables list.
        this.id = id;   return this;
    }
    var staticVariablesJOSN = { "parent_S_V" : 777 };
    staticVariable( currentClass, staticVariablesJOSN );
    // Setters, Getters, instanceMethods. [{}, {}];
    var instanceFunctions = [
        {
            key: 'uniqueID',
            get: function get() { return this.id; },
            set: function set(changeVal) { this.id = changeVal; }
        }
    ];
    instanceMethods( currentClass, instanceFunctions );
    return currentClass;
}(Object);
var Rectangle = function ( superClass ) {
    var currentClass = Rectangle;
    _inherits(currentClass, superClass); // Prototype Chain - Extends
    function Rectangle(id, width, height) { superClass.call(this, id); // Linking with SuperClass Constructor.
        this.width = width;
        this.height = height;   return this;
    }
    var staticVariablesJOSN = { "_staticVar" : 77777 };
    staticVariable( currentClass, staticVariablesJOSN );
    var staticFunctions = [
        {
            key: 'println',
            value: function println() { console.log('Static Method'); }
        }
    ];
    staticMethods(currentClass, staticFunctions);
    var instanceFunctions = [
        {
            key: 'setStaticVar',
            value: function setStaticVar(staticVal) {
                currentClass.parent_S_V = staticVal;
                console.log('SET Instance Method Parent Class Static Value : ', currentClass.parent_S_V);
            }
        }, {
            key: 'getStaticVar',
            value: function getStaticVar() {
                console.log('GET Instance Method Parent Class Static Value : ', currentClass.parent_S_V);
                return currentClass.parent_S_V;
            }
        }, {
            key: 'area',
            get: function get() {
                console.log('Area : ', this.width * this.height);
                return this.width * this.height;
                }
        }, {
            key: 'globalValue',
            get: function get() {
                console.log('GET ID : ', currentClass._staticVar);
                return currentClass._staticVar;
            },
            set: function set(value) {
                currentClass._staticVar = value;
                console.log('SET ID : ', currentClass._staticVar);
            }
        }
    ];
    instanceMethods( currentClass, instanceFunctions );
    return currentClass;
}(Shape);
// ===== ES5 Class Conversion Supported Functions =====
function defineProperties(target, props) {
    console.log(target, ' : ', props);
    for (var i = 0; i < props.length; i++) {
        var descriptor = props[i];
        descriptor.enumerable = descriptor.enumerable || false;
        descriptor.configurable = true;
        if ("value" in descriptor) descriptor.writable = true;
        Object.defineProperty(target, descriptor.key, descriptor);
    }
}
function staticMethods( currentClass, staticProps ) {
    defineProperties(currentClass, staticProps);
};
function instanceMethods( currentClass, protoProps ) {
    defineProperties(currentClass.prototype, protoProps);
};
function staticVariable( currentClass, staticVariales ) {
    // Get Key Set and get its corresponding value.
    // currentClass.key = value;
    for( var prop in staticVariales ) {
        console.log('Keys : Values');
        if( staticVariales.hasOwnProperty( prop ) ) {
            console.log(prop, ' : ', staticVariales[ prop ] );
            currentClass[ prop ] = staticVariales[ prop ];
        }
    }
};
function _inherits(subClass, superClass) {
    console.log( subClass, ' : extends : ', superClass );
    if (typeof superClass !== "function" && superClass !== null) {
        throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
    }
    subClass.prototype = Object.create(superClass && superClass.prototype, 
            { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });
    if (superClass)
        Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}

Het onderstaande codefragment is bedoeld om te testen. Elke instantie heeft zijn eigen kopie van instantieleden en algemene statische leden.

var objTest = new Rectangle('Yash_777', 8, 7);
console.dir(objTest);
var obj1 = new Rectangle('R_1', 50, 20);
Rectangle.println(); // Static Method
console.log( obj1 );    // Rectangle {id: "R_1", width: 50, height: 20}
obj1.area;              // Area :  1000
obj1.globalValue;       // GET ID :  77777
obj1.globalValue = 88;  // SET ID :  88
obj1.globalValue;       // GET ID :  88  
var obj2 = new Rectangle('R_2', 5, 70);
console.log( obj2 );    // Rectangle {id: "R_2", width: 5, height: 70}
obj2.area;              // Area :  350    
obj2.globalValue;       // GET ID :  88
obj2.globalValue = 999; // SET ID :  999
obj2.globalValue;       // GET ID :  999
console.log('Static Variable Actions.');
obj1.globalValue;        // GET ID :  999
console.log('Parent Class Static variables');
obj1.getStaticVar();    // GET Instance Method Parent Class Static Value :  777
obj1.setStaticVar(7);   // SET Instance Method Parent Class Static Value :  7
obj1.getStaticVar();    // GET Instance Method Parent Class Static Value :  7

statische methode oproepen worden gemaakt rechtstreeks op de klas en zijn niet vervalbaar op gevallen van de klas. Maar u kunt de oproepen tot statische leden van binnenuit een instantie bereiken.

SYNTAX gebruiken:

  this.constructor.staticfunctionName();
class MyClass {
    constructor() {}
    static staticMethod() {
        console.log('Static Method');
    }
}
MyClass.staticVar = 777;
var myInstance = new MyClass();
// calling from instance
myInstance.constructor.staticMethod();
console.log('From Inside Class : ',myInstance.constructor.staticVar);
// calling from class
MyClass.staticMethod();
console.log('Class : ', MyClass.staticVar);

ES6-klassen: ES2015-klassen zijn een eenvoudige suiker over het op prototype gebaseerde OO-patroon. Het hebben van een enkele handige declaratieve vorm maakt klassenpatronen gemakkelijker te gebruiken en moedigt de interoperabiliteit aan. Klassen ondersteunen prototype-gebaseerde overerving, supergesprekken, instantie en statische methoden en constructeurs.

Voorbeeld : verwijs mijn vorige bericht.


21

U kunt definiëren statische functies in Javascript met behulp van de staticTrefwoord:

class MyClass {
  static myStaticFunction() {
    return 42;
  }
}
MyClass.myStaticFunction(); // 42

Vanaf dit schrijven kunt u nog steeds geen statische eigenschappen (anders dan functies) in de klas definiëren. Statische eigenschappen zijn nog steeds een fase 3-voorstel , wat betekent dat ze geen deel uitmaken van JavaScript nog. Er is echter niets dat u stopt met eenvoudig toewijzen aan een klasse zoals u zou op een ander object:

class MyClass {}
MyClass.myStaticProperty = 42;
MyClass.myStaticProperty; // 42

Laatste noot: wees voorzichtig met het gebruik van statische objecten met erfenis – alle geërfde klassen Deel hetzelfde exemplaar van het object .


22

In JavaScript is er geen term of trefwoord statisch, maar we kunnen dergelijke gegevens rechtstreeks in functieobject plaatsen (zoals in elk ander object).

function f() {
    f.count = ++f.count || 1 // f.count is undefined at first
    alert("Call No " + f.count)
}
f(); // Call No 1
f(); // Call No 2

23

In JavaScript is alles een primitief type of een object.
Functies zijn objecten – (sleutelwaarde paren).

Wanneer u een functie maakt, maakt u twee objecten. Eén object dat de functie zelf en de andere vertegenwoordigt die het prototype van de functie vertegenwoordigt.

functie is in principe in die zin een object met de eigenschappen:

function name, 
arguments length 
and the functional prototype.

Dus waar de statische eigenschap instelt:
Twee plaatsen, hetzij in het functie-object of in het object van de functie prototype.

Hier is een fragment dat ervoor zorgt dat zelfs twee instanties worden geïnstantieerd, met behulp van het newJavaScript-sleutelwoord.

function C () { // function
  var privateProperty = "42";  
  this.publicProperty = "39";  
  this.privateMethod = function(){ 
   console.log(privateProperty);
  };
}
C.prototype.publicMethod = function () {    
  console.log(this.publicProperty);
};
C.prototype.staticPrototypeProperty = "4";
C.staticProperty = "3";
var i1 = new C(); // instance 1
var i2 = new C(); // instance 2
i1.privateMethod();
i1.publicMethod();
console.log(i1.__proto__.staticPrototypeProperty);
i1.__proto__.staticPrototypeProperty = "2";
console.log(i2.__proto__.staticPrototypeProperty);
console.log(i1.__proto__.constructor.staticProperty);
i1.__proto__.constructor.staticProperty = "9";
console.log(i2.__proto__.constructor.staticProperty);

Antwoord 24

Ik gebruik veel statische functievariabelen en het is echt jammer dat JS daar geen ingebouwd mechanisme voor heeft. Te vaak zie ik code waarin variabelen en functies in een buitenste bereik worden gedefinieerd, ook al worden ze alleen binnen één functie gebruikt. Dit is lelijk, foutgevoelig en vraagt gewoon om problemen…

Ik heb de volgende methode bedacht:

if (typeof Function.prototype.statics === 'undefined') {
  Function.prototype.statics = function(init) {
    if (!this._statics) this._statics = init ? init() : {};
    return this._statics;
  }
}

Dit voegt een ‘statica’-methode toe aan alle functies (ja, ontspan er gewoon over), wanneer het wordt aangeroepen, wordt een leeg object (_statics) aan het functie-object toegevoegd en geretourneerd. Als een init-functie wordt geleverd, wordt _statics ingesteld op init() resultaat.

Je kunt dan het volgende doen:

function f() {
  const _s = f.statics(() => ({ v1=3, v2=somefunc() });
  if (_s.v1==3) { ++_s.v1; _s.v2(_s.v1); }
} 

Als je dit vergelijkt met een IIFE dat het andere juiste antwoord is, heeft dit het nadeel dat er bij elke functieaanroep één toewijzing en één if wordt toegevoegd en een ‘_statics’-lid aan de functie wordt toegevoegd, maar er zijn een paar voordelen: de argumenten zijn er bovenaan niet in de interne functie, het gebruik van een ‘static’ in de interne functiecode is expliciet met een ‘_s.’ prefix, en het is over het algemeen eenvoudiger om naar te kijken en te begrijpen.


Antwoord 25

Samenvatting:

In ES6/ES 2015 werd het classtrefwoord geïntroduceerd met een begeleidend statictrefwoord. Houd er rekening mee dat dit syntactische suiker is boven het prototypische overervingsmodel dat javavscript belichaamt. Het trefwoord staticwerkt op de volgende manier voor methoden:

class Dog {
  static bark () {console.log('woof');}
  // classes are function objects under the hood
  // bark method is located on the Dog function object
  makeSound () { console.log('bark'); }
  // makeSound is located on the Dog.prototype object
}
// to create static variables just create a property on the prototype of the class
Dog.prototype.breed = 'Pitbull';
// So to define a static property we don't need the `static` keyword.
const fluffy = new Dog();
const vicky = new Dog();
console.log(fluffy.breed, vicky.breed);
// changing the static variable changes it on all the objects
Dog.prototype.breed = 'Terrier';
console.log(fluffy.breed, vicky.breed);

26

Ik heb het prototype gebruikt en op die manier werkte het:

class Cat extends Anima {
  constructor() {
    super(Cat.COLLECTION_NAME);
  }
}
Cat.COLLECTION_NAME = "cats";

of gebruik een statische getter:

class Cat extends Anima {
  constructor() {
    super(Cat.COLLECTION_NAME);
  }
  static get COLLECTION_NAME() {
    return "cats"
  }
}

27

Venniveau VAR’s zijn sorta zoals statica in de zin dat u de directe referentie kunt gebruiken en deze zijn beschikbaar voor alle delen van uw app


28

Werken met MVC-websites die jQuery gebruiken, ik hou ervan om ervoor te zorgen dat AJAX-acties binnen bepaalde gebeurtenissenhandlers alleen kunnen worden uitgevoerd zodra het vorige verzoek is voltooid. Ik gebruik een “statische” JQXHR-objectvariabele om dit te bereiken.

Gegeven de volgende knop:

<button type="button" onclick="ajaxAction(this, { url: '/SomeController/SomeAction' })">Action!</button>

Ik gebruik over het algemeen een iife zoals dit voor mijn klikhandler:

var ajaxAction = (function (jqXHR) {
    return function (sender, args) {
        if (!jqXHR || jqXHR.readyState == 0 || jqXHR.readyState == 4) {
            jqXHR = $.ajax({
                url: args.url,
                type: 'POST',
                contentType: 'application/json',
                data: JSON.stringify($(sender).closest('form').serialize()),
                success: function (data) {
                    // Do something here with the data.
                }
            });
        }
    };
})(null);

Antwoord 29

Als je een prototype wilt gebruiken, dan is er een manier

var p = function Person() {
    this.x = 10;
    this.y = 20;
}
p.prototype.counter = 0;
var person1 = new p();
person1.prototype = p.prototype;
console.log(person1.counter);
person1.prototype.counter++;
var person2 = new p();
person2.prototype = p.prototype;
console.log(person2.counter);
console.log(person1.counter);

Als u dit doet, heeft u vanaf elke instantie toegang tot de tellervariabele en wordt elke wijziging in de eigenschap onmiddellijk weergegeven!!

Other episodes