nous pouvons définir une étiquette ou une autre balise html avec l'attribut de style "dispaly: none" et définir une valeur de variable pour cette valeur et une opération sur cette valeur. Ne prenons pas de dur.
asghar
La solution la plus simple que j'ai trouvée: ne définissez pas du tout une variable statique dans la classe. Lorsque vous souhaitez utiliser une variable statique, définissez-la simplement là, puis, par exemple someFunc = () => { MyClass.myStaticVariable = 1; }. Ensuite, créez simplement une méthode statique pour renvoyer le membre statique, par exemple static getStatic() { return MyClass.myStaticVariable; }. Ensuite, vous pouvez simplement appeler MyClass.getStatic()de l'extérieur de la classe pour obtenir les données statiques!
Pixel
Réponses:
863
Si vous venez d'un langage orienté objet basé sur une classe et typé statiquement (comme Java, C ++ ou C #), je suppose que vous essayez de créer une variable ou une méthode associée à un "type" mais pas à une instance.
Un exemple utilisant une approche "classique", avec des fonctions constructeurs pourrait peut-être vous aider à comprendre les concepts de JavaScript OO de base:
functionMyClass(){// constructor functionvar 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 instancesMyClass.staticProperty ="baz";var myInstance =newMyClass();
staticPropertyest défini dans l'objet MyClass (qui est une fonction) et n'a rien à voir avec ses instances créées, JavaScript traite les fonctions comme des objets de première classe , étant un objet, vous pouvez affecter des propriétés à une fonction.
MISE À JOUR: ES6 a introduit la possibilité de déclarer des classes via le classmot - clé. C'est du sucre de syntaxe sur l'héritage basé sur un prototype existant.
Le staticmot-clé vous permet de définir facilement des propriétés ou des méthodes statiques dans une classe.
Voyons l'exemple ci-dessus implémenté avec les classes ES6:
classMyClass{// class constructor, equivalent to// the function body of a constructorconstructor(){const privateVariable ='private value';// Private variable at the constructor scopethis.publicVariable ='public value';// Public propertythis.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 instancesstatic staticProperty ='static value';static staticMethod(){
console.log(this.staticProperty);}}// We can add properties to the class prototypeMyClass.prototype.additionalMethod =function(){
console.log(this.publicVariable);};var myInstance =newMyClass();
myInstance.publicMethod();// "public value"
myInstance.additionalMethod();// "public value"
myInstance.privilegedMethod();// "private value"MyClass.staticMethod();// "static value"
Vraisemblablement privilegedMethodn'est pas équivalent à une méthode privée dans OO, car il semble qu'elle pourrait être appelée sur une instance de MyClass? Voulez-vous dire qu'il est privilégié car il peut y accéder privateVariable?
Dónal
3
Ne peut pas this.constructorêtre utilisé pour accéder aux variables statiques à partir des "méthodes d'instance"? Si oui, cela vaut la peine de l'ajouter à la réponse.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
1
Vous pouvez également mentionner des fonctions statiques dans votre exemple.
David Rodrigues
18
salut, je ne suis pas sûr d'être d'accord avec cette ligne // Variable statique partagée par toutes les instances 'MyClass.staticProperty = "baz";' quant à moi, cela implique que vous pouvez trouver baz de «myInstance.staticProperty» que vous ne pouvez bien sûr pas.
fullstacklife
5
Peut-être devrait-elle lire MyClass.prototype.staticProperty = "baz";ou pour être encore plus correcte aux principes OO la propriété statique devrait en fait être définie comme une fonction anonyme MyClass.prototype.staticProperty = function () {return staticVar;}et pour que toutes les instances accèdent à une seule variable qui pourrait également être modifiée avec un setter.
lindsaymacvean
535
Vous pouvez profiter du fait que les fonctions JS sont également des objets, ce qui signifie qu'elles peuvent avoir des propriétés.
function countMyself(){// Check to see if the counter has been initializedif(typeof countMyself.counter =='undefined'){// It has not... perform the initialization
countMyself.counter =0;}// Do something stupid to indicate the value
alert(++countMyself.counter);}
Si vous appelez cette fonction plusieurs fois, vous verrez que le compteur est incrémenté.
Et c'est probablement une bien meilleure solution que de polir l'espace de noms global avec une variable globale.
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.returnfunction(){return id++;};// Return and increment})();// Invoke the outer function after defining it.
Ce qui vous donne le même genre de résultat - sauf que, cette fois, la valeur incrémentée est retournée, au lieu d'être affichée.
comme raccourci, vous pouvez le faire countMyself.counter = countMyself.counter || initial_value;si la variable statique ne sera jamais falsey (chaîne fausse, 0, nulle ou vide)
Kip
3
Légèrement plus court et plus clair: (function () {var id = 0; function uniqueID () {return id ++;};}) ();
Je dirais que c'est la façon la plus idiomatique de le faire en JavaScript. Dommage qu'il n'obtienne pas trop de votes positifs grâce à d'autres méthodes qui sont probablement plus acceptables pour les personnes qui viennent d'autres langues.
1
Je reformulerais en utilisant «fermeture» plutôt que simplement «IIFE».
zendka
39
vous pouvez utiliser arguments.callee pour stocker des variables "statiques" (ceci est également utile dans une fonction anonyme):
Autant que je puisse comprendre, cette méthode a un (un seul?) Avantage sur la manière de pascal MARTIN: vous pouvez l'utiliser sur des fonctions anonymes. Un exemple de cela serait génial
Dan
27
arguments.calleeest obsolète.
Questions de Quolonel,
Je ridiculise JS tout le temps, mais calleecela me semblait une bonne chose. Je me demande pourquoi le hack a-t-il décidé de déprécier cela ...: |
user2173353
35
J'ai vu quelques réponses similaires, mais je voudrais mentionner que cet article le décrit le mieux, alors je voudrais le partager avec vous.
Voici un code qui en est tiré, que j'ai modifié pour obtenir un exemple complet qui, espérons-le, profite à la communauté car il peut être utilisé comme modèle de conception pour les classes.
Cela répond également à votre question:
functionPodcast(){// private variablesvar _somePrivateVariable =123;// object properties (read/write)this.title ='Astronomy Cast';this.description ='A fact-based journey through the galaxy.';this.link ='http://www.astronomycast.com';// for read access to _somePrivateVariable via immutableProp this.immutableProp =function(){return _somePrivateVariable;}// object functionthis.toString =function(){return'Title: '+this.title;}};// static propertyPodcast.FILE_EXTENSION ='mp3';// static functionPodcast.download =function(podcast){
console.log('Downloading '+ podcast +' ...');};
Dans cet exemple, vous pouvez accéder aux propriétés / fonctions statiques comme suit:
Notez que dans podcast.immutableProp (), nous avons une fermeture : La référence à _somePrivateVariable est conservée à l'intérieur de la fonction.
Vous pouvez même définir des getters et setters . Jetez un œil à cet extrait de code (où dest le prototype de l'objet pour lequel vous souhaitez déclarer une propriété, yest une variable privée non visible en dehors du constructeur):
// getters and settersvar d =Date.prototype;Object.defineProperty(d,"year",{get:function(){returnthis.getFullYear()},set:function(y){this.setFullYear(y)}});
Il définit la propriété d.yearvia getet setfonctionne - si vous ne spécifiez pas set, alors la propriété est en lecture seule et ne peut pas être modifiée (sachez que vous n'obtiendrez pas d'erreur si vous essayez de la définir, mais cela n'a aucun effet). Chaque propriété possède les attributs writable, configurable(permettent de changer après la déclaration) et enumerable(permet de l' utiliser comme recenseur), qui sont par défaut false. Vous pouvez les définir via definePropertydans le 3ème paramètre, par exemple enumerable: true.
Ce qui est également valable, c'est cette syntaxe:
// getters and setters - alternative syntaxvar obj ={ a:7,get b(){returnthis.a +1;},set c(x){this.a = x /2}};
qui définit une propriété lisible / inscriptible a, une propriété en lecture seule bet une propriété en écriture seule c, à travers laquelle la propriétéa est accessible.
Pour éviter un comportement inattendu au cas où vous auriez oublié le newmot - clé, je vous suggère d'ajouter ce qui suit à la fonction Podcast:
// instantiation helperfunctionPodcast(){if(false===(thisinstanceofPodcast)){returnnewPodcast();}// [... same as above ...]};
Désormais, les deux instanciations suivantes fonctionneront comme prévu:
var podcast =newPodcast();// normal usage, still allowedvar podcast =Podcast();// you can omit the new keyword because of the helper
La «nouvelle» instruction crée un nouvel objet et copie toutes les propriétés et méthodes, c.-à-d.
var a=newPodcast();var b=newPodcast();
a.title="a"; b.title="An "+b.title;
console.log(a.title);// "a"
console.log(b.title);// "An Astronomy Cast"
Notez également que dans certaines situations, il peut être utile d'utiliser l' returninstruction dans la fonction constructeur Podcastpour renvoyer un objet personnalisé protégeant les fonctions sur lesquelles la classe s'appuie en interne mais qui doivent être exposées. Ceci est expliqué plus en détail au chapitre 2 (Objets) de la série d'articles.
Vous pouvez le dire aet en bhériter Podcast. Maintenant, que se passe-t-il si vous souhaitez ajouter une méthode à Podcast qui s'applique à tous après aet qui ba été instanciée? Dans ce cas, utilisez le .prototypecomme suit:
console.log(a.titleAndLink());// "a [http://www.astronomycast.com]"
console.log(b.titleAndLink());// "An Astronomy Cast [http://www.astronomycast.com]"
Vous pouvez trouver plus de détails sur les prototypes ici . Si vous voulez faire plus d'héritage, je vous suggère de vous pencher sur cela .
Les séries d'articles que j'ai mentionnées ci-dessus sont fortement recommandées à lire, elles incluent également les sujets suivants:
Les fonctions
Objets
Prototypes
Application de nouvelles fonctions aux constructeurs
Levage
Insertion automatique de point-virgule
Propriétés et méthodes statiques
Notez que la "fonction" d' insertion automatique de point-virgule de JavaScript (comme mentionné dans 6.) est très souvent responsable de provoquer des problèmes étranges dans votre code. Par conséquent, je préfère le considérer comme un bug plutôt que comme une fonctionnalité.
Si vous souhaitez en savoir plus, voici un article MSDN assez intéressant sur ces sujets, certains d'entre eux décrits ici fournissent encore plus de détails.
Ce qui est également intéressant à lire (couvrant également les sujets mentionnés ci-dessus) sont les articles du guide JavaScript MDN :
Si vous voulez savoir comment émuler des outparamètres c # (comme dans DateTime.TryParse(str, out result)) en JavaScript, vous pouvez trouver un exemple de code ici.
Ceux d'entre vous qui travaillent avec IE (qui n'a pas de console pour JavaScript sauf si vous ouvrez les outils de développement à l'aide F12et ouvrez l'onglet console) peuvent trouver l'extrait de code suivant utile. Il vous permet d'utiliser console.log(msg);comme utilisé dans les exemples ci-dessus. Insérez-le juste avant la Podcastfonction.
Pour votre commodité, voici le code ci-dessus dans un extrait de code unique complet:
TypeScript est un moyen pratique d'utiliser des classes et de les compiler en JavaScript . Voici une aire de jeux où vous pouvez trouver des exemples vous montrant comment cela fonctionne. Même si vous n'utilisez pas TypeScript pour le moment, vous pouvez y jeter un œil, car vous pouvez comparer TypeScript avec le résultat JavaScript sur une vue côte à côte. La plupart des exemples sont simples, mais il existe également un exemple Raytracer que vous pouvez essayer instantanément. Je recommande particulièrement de regarder les exemples "Utilisation des classes", "Utilisation de l'héritage" et "Utilisation des génériques" en les sélectionnant dans la zone de liste déroulante - ce sont de beaux modèles que vous pouvez utiliser instantanément en JavaScript. Le tapuscrit est utilisé avec Angular.
Pour réaliser l' encapsulation des variables locales, des fonctions, etc. en JavaScript, je suggère d'utiliser un modèle comme le suivant (JQuery utilise la même technique):
<html><head></head><body><script>'use strict';// module pattern (self invoked function)const myModule =(function(context){// to allow replacement of the function, use 'var' otherwise keep 'const'// put variables and function with local module scope here:var print =function(str){if(str !==undefined) context.document.write(str);
context.document.write("<br/><br/>");return;}// ... more variables ...// main methodvar _main =function(title){if(title !==undefined) print(title);
print("<b>last modified: </b>"+ context.document.lastModified +"<br/>");// ... more code ...}// public methodsreturn{Main: _main
// ... more public methods, properties ...};})(this);// use module
myModule.Main("<b>Module demo</b>");</script></body></html>
Dans ECMAScript 6 , vous pouvez créer des fonctions statiques à l'aide du staticmot clé:
classFoo{static bar(){return'I am static.'}}//`bar` is a property of the classFoo.bar()// returns 'I am static.'//`bar` is not a property of instances of the classvar foo =newFoo()
foo.bar()//-> throws TypeError
Les classes ES6 n'introduisent aucune nouvelle sémantique pour la statique. Vous pouvez faire la même chose dans ES5 comme ceci:
//constructorvarFoo=function(){}Foo.bar =function(){return'I am static.'}Foo.bar()// returns 'I am static.'var foo =newFoo()
foo.bar()// throws TypeError
Vous pouvez attribuer à une propriété de Foocar en JavaScript les fonctions sont des objets.
Foo.bar;renvoie la fonction qui lui est affectée, pas la chaîne renvoyée par la fonction comme votre commentaire l'indique.
Pouvez-vous ajouter des informations sur la façon de définir (remplacer) une valeur statique dans ces deux exemples?
Flétrissement du
1
@Wilt dans les deux cas, une propriété "statique" n'est qu'une propriété de la fonction, vous la définissez et la remplacez comme vous le feriez pour toute autre propriété en JavaScript. Dans les deux cas, vous pouvez définir la barpropriété Fooà 3aimer ceci:Foo.bar = 3;
L'exemple et l'explication suivants sont tirés du livre Professional JavaScript for Web Developers 2nd Edition de Nicholas Zakas. C'est la réponse que je cherchais donc j'ai pensé qu'il serait utile de l'ajouter ici.
(function(){var name ='';Person=function(value){
name = value;};Person.prototype.getName =function(){return name;};Person.prototype.setName =function(value){
name = value;};}());var person1 =newPerson('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());// Jamesvar person2 =newPerson('Danielle');
console.log(person1.getName());// Danielle
console.log(person2.getName());// Danielle
Le Personconstructeur de cet exemple a accès au nom de la variable privée, tout comme les méthodes getName()et setName(). En utilisant ce modèle, la variable de nom devient statique et sera utilisée parmi toutes les instances. Cela signifie que l'appel setName()à une instance affecte toutes les autres instances. L'appel setName()ou la création d'une nouvelle Personinstance définit la variable de nom sur une nouvelle valeur. Cela oblige toutes les instances à retourner la même valeur.
Cela place l'objet Personne dans l'espace de noms global. Pas une solution que je recommanderais.
Ghola
Je ne pense pas que ce soit une vraie variable statique car elle est instanciée différemment avec chaque nouvel objet. Un objet statique doit être cohérent sur tous les objets hérités du prototype parent?
lindsaymacvean
1
@Ghola L'intention ici était d'expliquer comment créer une variable statique. L'espacement des noms correct et l'évitement des globaux est un sujet distinct qui peut avoir ajouté à la complexité de la réponse. C'est à l'utilisateur de déterminer comment attacher le constructeur sans polluer. Si c'est assez bon pour Nicholas Zakas, c'est assez bon pour moi.
Nate
@lindsaymacvean Il s'agit d'une variable statique car la valeur unique est partagée entre toutes les instances. C'est OK pour que la valeur change. Si une instance modifie la valeur, toutes les instances seront affectées. Il est peu probable qu'il soit utilisé exactement de la même manière que l'exemple ci-dessus. Permettre à la valeur d'être définie lors de l'instanciation, c'est simplement pour montrer que c'est possible. Un cas d'utilisation plus probable serait d'avoir uniquement le getter et le setter ou au moins de vérifier qu'il est réglé sur autre chose qu'indéfini.
Nate
15
Si vous utilisez la nouvelle syntaxe de classe, vous pouvez maintenant effectuer les opérations suivantes:
Ceci est utile lors de la construction de classes utilitaires statiques!
Indolering
1
Mais maintenant, la question est de savoir comment conserver une valeur et autoriser ses modifications avec un setter. Une fermeture serait nécessaire ou une propriété MyClassdéfinie en dehors de la construction de classe.
Si vous voulez déclarer des variables statiques pour créer des constantes dans votre application, j'ai trouvé que l'approche la plus simpliste était la suivante
À propos de l' classintroduction par ECMAScript 2015. Les autres réponses ne sont pas totalement claires.
Voici un exemple montrant comment créer un var statique staticVaravec le ClassName. varsynthax:
classMyClass{constructor(val){this.instanceVar = val;MyClass.staticVar =10;}}var class1 =newMyClass(1);
console.log(class1.instanceVar);// 1
console.log(class1.constructor.staticVar);// 10// New instance of MyClass with another valuevar class2 =newMyClass(3);
console.log(class1.instanceVar);// 1
console.log(class2.instanceVar);// 3
Pour accéder à la variable statique, nous utilisons la .constructorpropriété qui renvoie une référence à la fonction de constructeur d'objet qui a créé la classe. On peut l'appeler sur les deux instances créées:
Vous pouvez créer une variable statique en JavaScript comme ci-dessous. Voici countla variable statique.
varPerson=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 1Person.count =Person.count ?Person.count +1:1;}var p1 =newPerson('User p1');
console.log(p1.constructor.count);// prints 1var p2 =newPerson('User p2');
console.log(p2.constructor.count);// prints 2
Vous pouvez affecter des valeurs à la variable statique à l'aide de la Personfonction ou de l'une des instances:
// 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 PersonPerson.count =20;
console.log(p1.constructor.count);// prints 20
La chose la plus proche en JavaScript d'une variable statique est une variable globale - c'est simplement une variable déclarée en dehors de la portée d'un littéral de fonction ou d'objet:
var thisIsGlobal =1;function foo(){var thisIsNot =2;}
L'autre chose que vous pourriez faire serait de stocker des variables globales dans un objet littéral comme celui-ci:
var foo ={ bar :1}
Et puis accéder aux variabels comme ceci: foo.bar.
celui-ci m'a aidé à télécharger plusieurs fichiers ..... var foo = {counter: 1}; function moreFiles () {fileName = "File" + foo.counter; foo.counter = foo.counter + 1;
veer7
4
Pour condenser tous les concepts de classe ici, testez ceci:
varTest=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 classesvar test_var ="super private";//the only way to access the "super private" test_var is from herethis.privileged =function(){
console.log(test_var);}();Test.test_var ='protected';//protected variable: accessible only form inherited methods (prototype) AND child/inherited classesthis.init();};//end constructorTest.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);varJake=function(){}Jake.prototype =newTest();Jake.prototype.test =function(){
console.log('jake',Test.test_var);}var jake =newJake();
jake.test();//output: "protected"});//end domready
Eh bien, une autre façon de jeter un coup d'œil aux meilleures pratiques dans ces domaines est de simplement voir comment coffeescript traduit ces concepts.
#this is coffeescript
classTest#static@prop="static"#instance
constructor:(prop)->@prop= prop
console.log(@prop)
t =newTest('inst_prop');
console.log(Test.prop);//this is how the above is translated in plain js by the CS compilerTest=(function(){Test.prop ="static";functionTest(prop){this.prop = prop;
console.log(this.prop);}returnTest;})();
t =newTest('inst_prop');
console.log(Test.prop);
C'est un cas différent. Votre exemple concerne les portées.
challet
4
Il existe une autre approche, qui a résolu mes exigences après avoir parcouru ce fil. Cela dépend exactement de ce que vous voulez réaliser avec une "variable statique".
La propriété globale sessionStorage ou localStorage permet aux données d'être stockées pour la durée de la session, ou pour une période indéfinie plus longue jusqu'à ce qu'elles soient explicitement effacées, respectivement. Cela permet de partager des données entre toutes les fenêtres, cadres, onglets, fenêtres contextuelles, etc. de votre page / application et est beaucoup plus puissant qu'une simple "variable statique / globale" dans un segment de code.
Il évite tout problème avec la portée, la durée de vie, la sémantique, la dynamique, etc. des variables globales de niveau supérieur, c'est-à-dire Window.myglobal. Je ne sais pas à quel point c'est efficace, mais ce n'est pas important pour des quantités modestes de données, accessibles à des taux modestes.
Facilement accessible en tant que "sessionStorage.mydata = n'importe quoi" et récupéré de manière similaire. Voir «JavaScript: The Definitive Guide, Sixth Edition», David Flanagan, ISBN: 978-0-596-80552-4, chapitre 20, section 20.1. Ceci est facilement téléchargeable au format PDF par simple recherche, ou dans votre abonnement O'Reilly Safaribooks (qui vaut son pesant d'or).
Les fonctions créées avec le constructeur Function ne créent pas de fermetures à leurs contextes de création; ils sont toujours créés dans la portée globale.
var functionClass =function(){var currentClass =Shape;
_inherits(currentClass, superClass);function functionClass(){ superClass.call(this);// Linking with SuperClass Constructor.// Instance Variables list.this.id = id;returnthis;}}(SuperClass)
Fermetures - les copies de fermeture fonctionnent avec des données préservées.
Les copies de chaque fermeture sont créées dans une fonction avec leurs propres valeurs ou références libres. Chaque fois que vous utilisez une fonction dans une autre fonction, une fermeture est utilisée.
Une fermeture en JavaScript revient à conserver une copie de toutes les variables locales de sa fonction parente par les fonctions internes.
function closureFun( args ){// Local variable that ends up within closurevar num = args;
num++;returnfunction(){ console.log(num);}}var closure1 = closureFun(5);var closure2 = closureFun(777);
closure1();// 5
closure2();// 777
closure2();// 778
closure1();// 6
La méthode Object.defineProperty () définit une nouvelle propriété directement sur un objet ou modifie une propriété existante sur un objet et renvoie l'objet.
Créé quelques méthodes en utilisant `` , afin que chaque fois puisse comprendre facilement les classes de fonctions.
L'extrait de code ci-dessous consiste à tester Chaque instance a sa propre copie des membres d'instance et des membres statiques communs.
var objTest =newRectangle('Yash_777',8,7);
console.dir(objTest);var obj1 =newRectangle('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 =newRectangle('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
Les appels de méthode statique sont effectués directement sur la classe et ne sont pas appelables sur les instances de la classe. Mais vous pouvez réaliser les appels de membres statiques à l'intérieur d'une instance.
Utilisation de la syntaxe:
this.constructor.staticfunctionName();
classMyClass{constructor(){}static staticMethod(){
console.log('Static Method');}}MyClass.staticVar =777;var myInstance =newMyClass();// calling from instance
myInstance.constructor.staticMethod();
console.log('From Inside Class : ',myInstance.constructor.staticVar);// calling from classMyClass.staticMethod();
console.log('Class : ',MyClass.staticVar);
Classes ES6: Les classes ES2015 sont un simple sucre sur le modèle OO basé sur un prototype. Le fait d'avoir un seul formulaire déclaratif pratique facilite l'utilisation des modèles de classe et encourage l'interopérabilité. Les classes prennent en charge l'héritage basé sur des prototypes, les super appels, les méthodes et constructeurs d'instance et statiques.
Au moment d'écrire ces lignes, vous ne pouvez toujours pas définir de propriétés statiques (autres que des fonctions) au sein de la classe. Les propriétés statiques sont toujours une proposition de l'étape 3 , ce qui signifie qu'elles ne font pas encore partie de JavaScript. Cependant, rien ne vous empêche d'affecter simplement à une classe comme vous le feriez pour tout autre objet:
En JavaScript, il n'y a pas de terme ou de mot-clé statique, mais nous pouvons mettre ces données directement dans l'objet fonction (comme dans tout autre objet).
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
J'utilise beaucoup de variables de fonction statiques et c'est vraiment dommage que JS n'ait pas de mécanisme intégré pour cela. Trop souvent, je vois du code où les variables et les fonctions sont définies dans une portée externe, même si elles ne sont utilisées que dans une seule fonction. C'est moche, sujet aux erreurs et demande juste des ennuis ...
Cela ajoute une méthode «statique» à toutes les fonctions (oui, détendez-vous), lorsqu'elle est appelée, elle ajoute un objet vide (_statics) à l'objet fonction et le renvoie. Si une fonction init est fournie, _statics sera défini sur init () result.
Vous pouvez alors faire:
function f(){const _s = f.statics(()=>({ v1=3, v2=somefunc()});if(_s.v1==3){++_s.v1; _s.v2(_s.v1);}}
En comparant cela à un IIFE qui est l'autre bonne réponse, cela a l'inconvénient d'ajouter une affectation et une si à chaque appel de fonction et d'ajouter un membre '_statics' à la fonction, mais il y a quelques avantages: les arguments sont là à le haut pas dans la fonction interne, l'utilisation d'un 'statique' dans le code de la fonction interne est explicite avec un '_s'. préfixe, et il est globalement plus simple à regarder et à comprendre.
Dans ES6/ ES 2015, le classmot clé a été introduit avec un staticmot clé accompagné . Gardez à l'esprit qu'il s'agit de sucre syntaxique par rapport au modèle d'héritage prototypique qu'incarne javavscript. Le staticmot-clé fonctionne de la manière suivante pour les méthodes:
classDog{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 classDog.prototype.breed ='Pitbull';// So to define a static property we don't need the `static` keyword.const fluffy =newDog();const vicky =newDog();
console.log(fluffy.breed, vicky.breed);// changing the static variable changes it on all the objectsDog.prototype.breed ='Terrier';
console.log(fluffy.breed, vicky.breed);
Les variables au niveau de la fenêtre sont en quelque sorte des statiques dans le sens où vous pouvez utiliser une référence directe et elles sont disponibles pour toutes les parties de votre application
Une bien meilleure description de ces variables est «globale», plutôt que statique.
Patrick M
0
Il n'y a pas de variable statique en Javascript. Ce langage est orienté objet basé sur des prototypes, il n'y a donc pas de classes, mais des prototypes d'où les objets se "copient".
Vous pouvez les simuler avec des variables globales ou avec du prototypage (en ajoutant une propriété au prototype):
Cette méthode fonctionne, mais vous polissez leFunction.prototype
Dan
@Dan: Je crois comprendre que ce serait juste pour le cercle et non pour la fonction. C'est du moins ce que Chrome essaie de me dire: function circle() {}| circle.prototype| circle.prototype.pi = 3.14| circle.prototype| Function.prototype| Function.__proto__(si c'est ce que vous vouliez dire)
Aktau
0
En travaillant avec les sites Web MVC qui utilisent jQuery, j'aime m'assurer que les actions AJAX dans certains gestionnaires d'événements ne peuvent être exécutées qu'une fois la demande précédente terminée. J'utilise une variable d'objet jqXHR "statique" pour y parvenir.
J'utilise généralement un IIFE comme celui-ci pour mon gestionnaire de clics:
var ajaxAction =(function(jqXHR){returnfunction(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);
En faisant cela, vous pourrez accéder à la variable de compteur à partir de n'importe quelle instance et tout changement dans la propriété sera immédiatement reflété !!
someFunc = () => { MyClass.myStaticVariable = 1; }
. Ensuite, créez simplement une méthode statique pour renvoyer le membre statique, par exemplestatic getStatic() { return MyClass.myStaticVariable; }
. Ensuite, vous pouvez simplement appelerMyClass.getStatic()
de l'extérieur de la classe pour obtenir les données statiques!Réponses:
Si vous venez d'un langage orienté objet basé sur une classe et typé statiquement (comme Java, C ++ ou C #), je suppose que vous essayez de créer une variable ou une méthode associée à un "type" mais pas à une instance.
Un exemple utilisant une approche "classique", avec des fonctions constructeurs pourrait peut-être vous aider à comprendre les concepts de JavaScript OO de base:
staticProperty
est défini dans l'objet MyClass (qui est une fonction) et n'a rien à voir avec ses instances créées, JavaScript traite les fonctions comme des objets de première classe , étant un objet, vous pouvez affecter des propriétés à une fonction.MISE À JOUR: ES6 a introduit la possibilité de déclarer des classes via le
class
mot - clé. C'est du sucre de syntaxe sur l'héritage basé sur un prototype existant.Le
static
mot-clé vous permet de définir facilement des propriétés ou des méthodes statiques dans une classe.Voyons l'exemple ci-dessus implémenté avec les classes ES6:
la source
privilegedMethod
n'est pas équivalent à une méthode privée dans OO, car il semble qu'elle pourrait être appelée sur une instance de MyClass? Voulez-vous dire qu'il est privilégié car il peut y accéderprivateVariable
?this.constructor
être utilisé pour accéder aux variables statiques à partir des "méthodes d'instance"? Si oui, cela vaut la peine de l'ajouter à la réponse.MyClass.prototype.staticProperty = "baz";
ou pour être encore plus correcte aux principes OO la propriété statique devrait en fait être définie comme une fonction anonymeMyClass.prototype.staticProperty = function () {return staticVar;}
et pour que toutes les instances accèdent à une seule variable qui pourrait également être modifiée avec un setter.Vous pouvez profiter du fait que les fonctions JS sont également des objets, ce qui signifie qu'elles peuvent avoir des propriétés.
Par exemple, en citant l'exemple donné sur l'article (maintenant disparu) Variables statiques en Javascript :
Si vous appelez cette fonction plusieurs fois, vous verrez que le compteur est incrémenté.
Et c'est probablement une bien meilleure solution que de polir l'espace de noms global avec une variable globale.
Et voici une autre solution possible, basée sur une fermeture: Astuce pour utiliser des variables statiques en javascript :
Ce qui vous donne le même genre de résultat - sauf que, cette fois, la valeur incrémentée est retournée, au lieu d'être affichée.
la source
countMyself.counter = countMyself.counter || initial_value;
si la variable statique ne sera jamais falsey (chaîne fausse, 0, nulle ou vide)===
pour lestypeof
contrôles sinon vous obtiendrez une coercition étrange.Vous le faites via une IIFE (expression de fonction immédiatement invoquée):
la source
vous pouvez utiliser arguments.callee pour stocker des variables "statiques" (ceci est également utile dans une fonction anonyme):
la source
arguments.callee
est obsolète.callee
cela me semblait une bonne chose. Je me demande pourquoi le hack a-t-il décidé de déprécier cela ...: |J'ai vu quelques réponses similaires, mais je voudrais mentionner que cet article le décrit le mieux, alors je voudrais le partager avec vous.
Voici un code qui en est tiré, que j'ai modifié pour obtenir un exemple complet qui, espérons-le, profite à la communauté car il peut être utilisé comme modèle de conception pour les classes.
Cela répond également à votre question:
Dans cet exemple, vous pouvez accéder aux propriétés / fonctions statiques comme suit:
Et les propriétés / fonctions de l' objet sont simplement les suivantes:
Notez que dans podcast.immutableProp (), nous avons une fermeture : La référence à _somePrivateVariable est conservée à l'intérieur de la fonction.
Vous pouvez même définir des getters et setters . Jetez un œil à cet extrait de code (où
d
est le prototype de l'objet pour lequel vous souhaitez déclarer une propriété,y
est une variable privée non visible en dehors du constructeur):Il définit la propriété
d.year
viaget
etset
fonctionne - si vous ne spécifiez passet
, alors la propriété est en lecture seule et ne peut pas être modifiée (sachez que vous n'obtiendrez pas d'erreur si vous essayez de la définir, mais cela n'a aucun effet). Chaque propriété possède les attributswritable
,configurable
(permettent de changer après la déclaration) etenumerable
(permet de l' utiliser comme recenseur), qui sont par défautfalse
. Vous pouvez les définir viadefineProperty
dans le 3ème paramètre, par exempleenumerable: true
.Ce qui est également valable, c'est cette syntaxe:
qui définit une propriété lisible / inscriptible
a
, une propriété en lecture seuleb
et une propriété en écriture seulec
, à travers laquelle la propriétéa
est accessible.Usage:
Remarques:
Pour éviter un comportement inattendu au cas où vous auriez oublié le
new
mot - clé, je vous suggère d'ajouter ce qui suit à la fonctionPodcast
:Désormais, les deux instanciations suivantes fonctionneront comme prévu:
La «nouvelle» instruction crée un nouvel objet et copie toutes les propriétés et méthodes, c.-à-d.
Notez également que dans certaines situations, il peut être utile d'utiliser l'
return
instruction dans la fonction constructeurPodcast
pour renvoyer un objet personnalisé protégeant les fonctions sur lesquelles la classe s'appuie en interne mais qui doivent être exposées. Ceci est expliqué plus en détail au chapitre 2 (Objets) de la série d'articles.Vous pouvez le dire
a
et enb
hériterPodcast
. Maintenant, que se passe-t-il si vous souhaitez ajouter une méthode à Podcast qui s'applique à tous aprèsa
et quib
a été instanciée? Dans ce cas, utilisez le.prototype
comme suit:Maintenant, appelez encore
a
etb
encore:Vous pouvez trouver plus de détails sur les prototypes ici . Si vous voulez faire plus d'héritage, je vous suggère de vous pencher sur cela .
Les séries d'articles que j'ai mentionnées ci-dessus sont fortement recommandées à lire, elles incluent également les sujets suivants:
Notez que la "fonction" d' insertion automatique de point-virgule de JavaScript (comme mentionné dans 6.) est très souvent responsable de provoquer des problèmes étranges dans votre code. Par conséquent, je préfère le considérer comme un bug plutôt que comme une fonctionnalité.
Si vous souhaitez en savoir plus, voici un article MSDN assez intéressant sur ces sujets, certains d'entre eux décrits ici fournissent encore plus de détails.
Ce qui est également intéressant à lire (couvrant également les sujets mentionnés ci-dessus) sont les articles du guide JavaScript MDN :
Si vous voulez savoir comment émuler des
out
paramètres c # (comme dansDateTime.TryParse(str, out result)
) en JavaScript, vous pouvez trouver un exemple de code ici.Ceux d'entre vous qui travaillent avec IE (qui n'a pas de console pour JavaScript sauf si vous ouvrez les outils de développement à l'aide F12et ouvrez l'onglet console) peuvent trouver l'extrait de code suivant utile. Il vous permet d'utiliser
console.log(msg);
comme utilisé dans les exemples ci-dessus. Insérez-le juste avant laPodcast
fonction.Pour votre commodité, voici le code ci-dessus dans un extrait de code unique complet:
Afficher l'extrait de code
Remarques:
Quelques bons conseils, astuces et recommandations sur la programmation JavaScript en général, vous pouvez les trouver ici (meilleures pratiques JavaScript) et là ('var' versus 'let') . Cet article est également recommandé sur les transtypages implicites (coercition) .
TypeScript est un moyen pratique d'utiliser des classes et de les compiler en JavaScript . Voici une aire de jeux où vous pouvez trouver des exemples vous montrant comment cela fonctionne. Même si vous n'utilisez pas TypeScript pour le moment, vous pouvez y jeter un œil, car vous pouvez comparer TypeScript avec le résultat JavaScript sur une vue côte à côte. La plupart des exemples sont simples, mais il existe également un exemple Raytracer que vous pouvez essayer instantanément. Je recommande particulièrement de regarder les exemples "Utilisation des classes", "Utilisation de l'héritage" et "Utilisation des génériques" en les sélectionnant dans la zone de liste déroulante - ce sont de beaux modèles que vous pouvez utiliser instantanément en JavaScript. Le tapuscrit est utilisé avec Angular.
Pour réaliser l' encapsulation des variables locales, des fonctions, etc. en JavaScript, je suggère d'utiliser un modèle comme le suivant (JQuery utilise la même technique):
Bien sûr, vous pouvez - et devez - mettre le code du script dans un
*.js
fichier séparé ; c'est juste écrit en ligne pour garder l'exemple court.Les fonctions auto-appelantes (également appelées IIFE = Immediateely Invoked Function Expression) sont décrites plus en détail ici .
la source
la source
Réponse mise à jour:
Dans ECMAScript 6 , vous pouvez créer des fonctions statiques à l'aide du
static
mot clé:Les classes ES6 n'introduisent aucune nouvelle sémantique pour la statique. Vous pouvez faire la même chose dans ES5 comme ceci:
Vous pouvez attribuer à une propriété de
Foo
car en JavaScript les fonctions sont des objets.la source
Foo.bar;
renvoie la fonction qui lui est affectée, pas la chaîne renvoyée par la fonction comme votre commentaire l'indique.bar
propriétéFoo
à3
aimer ceci:Foo.bar = 3;
L'exemple et l'explication suivants sont tirés du livre Professional JavaScript for Web Developers 2nd Edition de Nicholas Zakas. C'est la réponse que je cherchais donc j'ai pensé qu'il serait utile de l'ajouter ici.
Le
Person
constructeur de cet exemple a accès au nom de la variable privée, tout comme les méthodesgetName()
etsetName()
. En utilisant ce modèle, la variable de nom devient statique et sera utilisée parmi toutes les instances. Cela signifie que l'appelsetName()
à une instance affecte toutes les autres instances. L'appelsetName()
ou la création d'une nouvellePerson
instance définit la variable de nom sur une nouvelle valeur. Cela oblige toutes les instances à retourner la même valeur.la source
Si vous utilisez la nouvelle syntaxe de classe, vous pouvez maintenant effectuer les opérations suivantes:
Cela crée effectivement une variable statique en JavaScript.
la source
MyClass
définie en dehors de la construction de classe.Si vous voulez déclarer des variables statiques pour créer des constantes dans votre application, j'ai trouvé que l'approche la plus simpliste était la suivante
la source
À propos de l'
class
introduction par ECMAScript 2015. Les autres réponses ne sont pas totalement claires.Voici un exemple montrant comment créer un var statique
staticVar
avec leClassName
.var
synthax:Pour accéder à la variable statique, nous utilisons la
.constructor
propriété qui renvoie une référence à la fonction de constructeur d'objet qui a créé la classe. On peut l'appeler sur les deux instances créées:la source
Il existe d'autres réponses similaires, mais aucune d'entre elles ne m'a séduit. Voici ce que j'ai fini avec:
la source
En plus du reste, il existe actuellement un projet (proposition de l' étape 2 ) sur les propositions de l'ECMA qui introduit
static
les domaines publics dans les classes. ( les champs privés ont été pris en compte )En utilisant l'exemple de la proposition, la
static
syntaxe proposée ressemblera à ceci:et être équivalent à ce que d'autres ont souligné:
Vous pouvez ensuite y accéder via
CustomDate.epoch
.Vous pouvez suivre la nouvelle proposition dans
proposal-static-class-features
.Actuellement, babel prend en charge cette fonctionnalité avec le plugin de propriétés de classe transform que vous pouvez utiliser. De plus, bien que toujours en cours,
V8
il le met en œuvre .la source
Vous pouvez créer une variable statique en JavaScript comme ci-dessous. Voici
count
la variable statique.Vous pouvez affecter des valeurs à la variable statique à l'aide de la
Person
fonction ou de l'une des instances:la source
Si vous vouliez créer une variable statique globale:
Remplacez la variable par la suivante:
la source
La chose la plus proche en JavaScript d'une variable statique est une variable globale - c'est simplement une variable déclarée en dehors de la portée d'un littéral de fonction ou d'objet:
L'autre chose que vous pourriez faire serait de stocker des variables globales dans un objet littéral comme celui-ci:
Et puis accéder aux variabels comme ceci:
foo.bar
.la source
Pour condenser tous les concepts de classe ici, testez ceci:
Eh bien, une autre façon de jeter un coup d'œil aux meilleures pratiques dans ces domaines est de simplement voir comment coffeescript traduit ces concepts.
la source
En JavaScript, les variables sont statiques par défaut. Exemple :
La valeur de x est incrémentée de 1 toutes les 1000 millisecondes.
Il imprimera 1,2,3 ainsi de suite
la source
Il existe une autre approche, qui a résolu mes exigences après avoir parcouru ce fil. Cela dépend exactement de ce que vous voulez réaliser avec une "variable statique".
La propriété globale sessionStorage ou localStorage permet aux données d'être stockées pour la durée de la session, ou pour une période indéfinie plus longue jusqu'à ce qu'elles soient explicitement effacées, respectivement. Cela permet de partager des données entre toutes les fenêtres, cadres, onglets, fenêtres contextuelles, etc. de votre page / application et est beaucoup plus puissant qu'une simple "variable statique / globale" dans un segment de code.
Il évite tout problème avec la portée, la durée de vie, la sémantique, la dynamique, etc. des variables globales de niveau supérieur, c'est-à-dire Window.myglobal. Je ne sais pas à quel point c'est efficace, mais ce n'est pas important pour des quantités modestes de données, accessibles à des taux modestes.
Facilement accessible en tant que "sessionStorage.mydata = n'importe quoi" et récupéré de manière similaire. Voir «JavaScript: The Definitive Guide, Sixth Edition», David Flanagan, ISBN: 978-0-596-80552-4, chapitre 20, section 20.1. Ceci est facilement téléchargeable au format PDF par simple recherche, ou dans votre abonnement O'Reilly Safaribooks (qui vaut son pesant d'or).
la source
Les classes / fonctions n'autorisent qu'un seul constructeur pour sa portée d'objet.
Function Hoisting, declarations & expressions
Fermetures - les copies de fermeture fonctionnent avec des données préservées.
Classes de fonctions ES5 : utilise Object.defineProperty (O, P, Attributes)
Créé quelques méthodes en utilisant `` , afin que chaque fois puisse comprendre facilement les classes de fonctions.
L'extrait de code ci-dessous consiste à tester Chaque instance a sa propre copie des membres d'instance et des membres statiques communs.
Classes ES6: Les classes ES2015 sont un simple sucre sur le modèle OO basé sur un prototype. Le fait d'avoir un seul formulaire déclaratif pratique facilite l'utilisation des modèles de classe et encourage l'interopérabilité. Les classes prennent en charge l'héritage basé sur des prototypes, les super appels, les méthodes et constructeurs d'instance et statiques.
Exemple : référez-vous à mon post précédent.
la source
Il existe 4 façons d'émuler des variables statiques locales fonctionnelles en Javascript.
Méthode 1: utilisation des propriétés d'objet fonction (prise en charge dans les anciens navigateurs)
Méthode 2: à l'aide d'une fermeture, variante 1 (prise en charge dans les anciens navigateurs)
Méthode 3: à l'aide d'une fermeture, variante 2 (également prise en charge dans les anciens navigateurs)
Méthode 4: à l'aide d'une fermeture, variante 3 (nécessite la prise en charge d'EcmaScript 2015)
la source
Vous pouvez définir des fonctions statiques en JavaScript à l'aide du
static
mot clé:Au moment d'écrire ces lignes, vous ne pouvez toujours pas définir de propriétés statiques (autres que des fonctions) au sein de la classe. Les propriétés statiques sont toujours une proposition de l'étape 3 , ce qui signifie qu'elles ne font pas encore partie de JavaScript. Cependant, rien ne vous empêche d'affecter simplement à une classe comme vous le feriez pour tout autre objet:
Remarque finale: soyez prudent lorsque vous utilisez des objets statiques avec héritage - toutes les classes héritées partagent la même copie de l'objet .
la source
En JavaScript, il n'y a pas de terme ou de mot-clé statique, mais nous pouvons mettre ces données directement dans l'objet fonction (comme dans tout autre objet).
la source
J'utilise beaucoup de variables de fonction statiques et c'est vraiment dommage que JS n'ait pas de mécanisme intégré pour cela. Trop souvent, je vois du code où les variables et les fonctions sont définies dans une portée externe, même si elles ne sont utilisées que dans une seule fonction. C'est moche, sujet aux erreurs et demande juste des ennuis ...
J'ai trouvé la méthode suivante:
Cela ajoute une méthode «statique» à toutes les fonctions (oui, détendez-vous), lorsqu'elle est appelée, elle ajoute un objet vide (_statics) à l'objet fonction et le renvoie. Si une fonction init est fournie, _statics sera défini sur init () result.
Vous pouvez alors faire:
En comparant cela à un IIFE qui est l'autre bonne réponse, cela a l'inconvénient d'ajouter une affectation et une si à chaque appel de fonction et d'ajouter un membre '_statics' à la fonction, mais il y a quelques avantages: les arguments sont là à le haut pas dans la fonction interne, l'utilisation d'un 'statique' dans le code de la fonction interne est explicite avec un '_s'. préfixe, et il est globalement plus simple à regarder et à comprendre.
la source
Sommaire:
Dans
ES6
/ ES 2015, leclass
mot clé a été introduit avec unstatic
mot clé accompagné . Gardez à l'esprit qu'il s'agit de sucre syntaxique par rapport au modèle d'héritage prototypique qu'incarne javavscript. Lestatic
mot-clé fonctionne de la manière suivante pour les méthodes:la source
J'ai utilisé le prototype et ça a fonctionné ainsi:
ou en utilisant un getter statique:
la source
Les variables au niveau de la fenêtre sont en quelque sorte des statiques dans le sens où vous pouvez utiliser une référence directe et elles sont disponibles pour toutes les parties de votre application
la source
Il n'y a pas de variable statique en Javascript. Ce langage est orienté objet basé sur des prototypes, il n'y a donc pas de classes, mais des prototypes d'où les objets se "copient".
Vous pouvez les simuler avec des variables globales ou avec du prototypage (en ajoutant une propriété au prototype):
la source
Function.prototype
function circle() {}
|circle.prototype
|circle.prototype.pi = 3.14
|circle.prototype
|Function.prototype
|Function.__proto__
(si c'est ce que vous vouliez dire)En travaillant avec les sites Web MVC qui utilisent jQuery, j'aime m'assurer que les actions AJAX dans certains gestionnaires d'événements ne peuvent être exécutées qu'une fois la demande précédente terminée. J'utilise une variable d'objet jqXHR "statique" pour y parvenir.
Étant donné le bouton suivant:
J'utilise généralement un IIFE comme celui-ci pour mon gestionnaire de clics:
la source
Si vous souhaitez utiliser un prototype, il existe un moyen
En faisant cela, vous pourrez accéder à la variable de compteur à partir de n'importe quelle instance et tout changement dans la propriété sera immédiatement reflété !!
la source