Statiniai kintamieji javascript

Kaip sukurti statinius kintamuosius javascript?

553
08 окт. nustatė Rajat 08 okt. 2009-10-08 07:31 '09, 7:31 val. 2009-10-08 07:31
@ 36 atsakymai
  • 1
  • 2

Jei pradėsite nuo klasių pagrįstos objekto kalbos (pvz., „Java“, „C ++“ arba „C #“), manau, kad bandote sukurti kintamąjį arba metodą, susietą su „tipu“, bet ne su egzemplioriumi.

Pavyzdžiui, naudojant „klasikinį“ metodą, su konstruktoriaus funkcijomis, galbūt galite padėti suprasti pagrindinio „OO JavaScript“ sąvokas:

 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(); 

staticProperty apibrėžta „MyClass“ objekte (kuris yra funkcija) ir neturi nieko bendro su sukurtomis instancijomis, „JavaScript“ funkcijoms priskiriamos kaip pirmos klasės objektai , todėl kaip objektas galite priskirti funkcijas funkcijai.

743
08 окт. atsakymą pateikė CMS 08 okt. 2009-10-08 07:49 '09 ne 7:49 2009-10-08 07:49

Galite pasinaudoti tuo, kad JS funkcijos taip pat yra objektai, o tai reiškia, kad jie gali turėti savybių.

Pavyzdžiui, pateikiant pavyzdį iš „ Static Variables“ straipsnio „Javascript“, kuris dabar dingo:

 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); } 

Jei šią funkciją skambinate kelis kartus, pamatysite skaitiklio prieaugį.

border=0

Ir tai tikriausiai yra geresnis sprendimas, nei pasaulinės vardų erdvės perjungimas su pasauliniu kintamuoju.


Ir čia yra dar vienas galimas sprendimas, grindžiamas uždarymu: „ Statikos kintamųjų„ javascript “naudojimas :

 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. 

Kuris suteikia jums tą patį rezultatą - išskyrus tai, kad šį kartą vertė grąžinama su pridėta verte, o ne rodoma.

465
08 окт. atsakymą pateikė Pascal MARTIN 08 spalis 2009-10-08 07:37 '09 at 7:37 AM 2009-10-08 07:37

Tai darote per IIFE (nedelsiant vadinama funkcijų išraiška):

 var incr = (function () { var i = 1; return function () { return i++; } })(); incr(); // returns 1 incr(); // returns 2 
60
30 марта '13 в 13:02 2013-03-30 13:02 atsakymą pateikė khoomeister kovo 13 d. 13:02 2013-03-30 13:02

Galite naudoti argument.callee, kad išsaugotumėte "statinius" kintamuosius (tai taip pat naudinga anoniminei funkcijai):

 function () { arguments.callee.myStaticVar = arguments.callee.myStaticVar || 1; arguments.callee.myStaticVar++; alert(arguments.callee.myStaticVar); } 
36
06 нояб. atsakymas pateiktas gpilotino 06 lapkritis 2009-11-06 14:19 '09 ne 14:19 2009-11-06 14:19
 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(); 
24
28 февр. atsakymas, kurį pateikė jim_zike_huang 28 vasaris 2012-02-28 23:08 '12, 23:08, 2012-02-28 23:08

Mačiau keletą panašių atsakymų, bet norėčiau paminėti, kad šis pranešimas geriausiai apibūdina viską, d norėčiau pasidalinti ja su jumis.

Čia yra iš jo paimtas kodas, kurį modifikavau, kad gautume išsamų pavyzdį, kuris, tikiuosi, bus naudingas bendruomenei, nes jis gali būti naudojamas kaip klasių dizaino šablonas.

Jis taip pat atsako į jūsų klausimą:

 function Podcast() { // private variables var _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 function this.toString = function() { return 'Title: ' + this.title; } }; // static property Podcast.FILE_EXTENSION = 'mp3'; // static function Podcast.download = function(podcast) { console.log('Downloading ' + podcast + ' ...'); }; 

Šiame pavyzdyje galite pasiekti statines savybes / funkcijas :

 // access static properties/functions Podcast.FILE_EXTENSION; // 'mp3' Podcast.download('Astronomy cast'); // 'Downloading Astronomy cast ...' 

Ir objekto ypatybės / funkcijos yra paprastos:

 // access object properties/functions var podcast = new Podcast(); podcast.title = 'The Simpsons'; console.log(podcast.toString()); // Title: The Simpsons console.log(podcast.immutableProp()); // 123 

Atkreipkite dėmesį, kad podcast.immutableProp () mes turime uždarymą: nuoroda į _somePrivateVariable yra saugoma funkcijos viduje.

Jūs netgi galite apibrėžti getters ir seters . Pažvelkite į šį kodo fragmentą (kur d yra objekto, dėl kurio norite deklaruoti turtą, prototipas, y yra privatus kintamasis, kuris nėra matomas už konstruktoriaus):

 // getters and setters var d = Date.prototype; Object.defineProperty(d, "year", { get: function() {return this.getFullYear() }, set: function(y) { this.setFullYear(y) } }); 

Jis apibrėžia d.year nuosavybės per get ir set funkcijas - jei nenurodote set , tada nuosavybė yra skaitoma tik ir negali būti pakeista (nepamirškite, kad negausite klaidos, jei bandysite ją nustatyti, bet jis neturi jokio poveikio). Kiekviena nuosavybė yra writable , configurable (leidžia keisti po deklaracijos) ir enumerable (leisti naudoti kaip skaitiklio) atributus, kurie pagal nutylėjimą yra false . Pavyzdžiui, galite nustatyti juos per defineProperty trečiąjį parametrą. enumerable: true .

Taip pat yra sintaksė:

 // getters and setters - alternative syntax var obj = { a: 7, get b() {return this.a + 1;}, set c(x) {this.a = x / 2} }; 

kuris apibrėžia nuskaitymo / rašymo ypatybę a , tik skaitomą b turtą ir tik rašomą c turtą, per kurį galite pasiekti turtą.

Taikymas:

 console.log(obj.a); console.log(obj.b); // output: 7, 8 obj.c=40; console.log(obj.a); console.log(obj.b); // output: 20, 21 

Pastabos:

Jei norite išvengti netikėto elgesio, jei pamiršote new raktinį žodį, siūlau į Podcast funkciją pridėti:

 // instantiation helper function Podcast() { if(false === (this instanceof Podcast)) { return new Podcast(); } // [... same as above ...] }; 

Dabar abu šie atvejai veiks taip, kaip tikėtasi:

 var podcast = new Podcast(); // normal usage, still allowed var podcast = Podcast(); // you can omit the new keyword because of the helper 

Naujasis operatorius sukuria naują objektą ir kopijuoja visas savybes ir metodus, t.

 var a=new Podcast(); var b=new Podcast(); a.title="a"; b.title="An "+b.title; console.log(a.title); // "a" console.log(b.title); // "An Astronomy Cast" 

Taip pat atkreipkite dėmesį, kad kai kuriose situacijose gali būti naudinga naudoti „ Podcast konstruktoriaus funkciją, kad grąžintumėte pasirinktinius objektus, kurie apsaugo funkcijas, kuriomis pasitikima savimi, bet kuri turi būti paveikta. Tai išsamiau paaiškinta straipsnio serijos 2 skyriuje (Objektai).

Galite pasakyti, kad a ir b yra paveldėti iš „ Podcast . Dabar, kas, jei norite pridėti metodą prie „Podcast“, kuri taikoma visiems po a ir b , buvo instanced? Tokiu atveju naudokite .prototype taip:

 Podcast.prototype.titleAndLink = function() { return this.title + " [" + this.link + "]"; }; 

Dabar vėl skambinkite a ir b :

 console.log(a.titleAndLink()); // "a [http://www.astronomycast.com]" console.log(b.titleAndLink()); // "An Astronomy Cast [http://www.astronomycast.com]" 

Daugiau apie prototipus skaitykite čia . Jei norite daugiau paveldėti, siūlau tai ištirti.


Pirmiau minėtų straipsnių serija, rekomenduojama skaityti, taip pat apima šias temas

  • Funkcijos
  • Objektai
  • Prototipai
  • Naujų konstruktorių funkcijų vykdymas
  • Keltuvas
  • Automatinis kabliataškis
  • Statinės savybės ir metodai

Atkreipkite dėmesį , kad automatinė semikolono „ JavaScript“ funkcija (kaip minėta 6.) yra labai dažnai atsakinga už keistų problemų kodą. Todėl norėčiau, kad tai būtų klaida, o ne kaip funkcija.

Jei norite sužinoti daugiau, čia yra gana įdomus MSDN straipsnis apie šias temas, iš kurių kai kurios čia aprašytos, pateikia dar išsamesnę informaciją.

Įdomu skaityti (taip pat ir pirmiau minėtas temas) yra MDN „JavaScript“ vadovo straipsniai :


Tie iš jūsų, kurie dirba su „IE“ (neturintys „JavaScript“ konsolės, jei nesate atidarę kūrėjų įrankių naudodami F12 ir atidarę konsolės skirtuką), gali rasti tokį fragmentą naudinga. Tai leidžia naudoti console.log(msg); kaip nurodyta aukščiau pateiktuose pavyzdžiuose. Tiesiog įklijuokite jį prieš „ Podcast funkciją.

Jūsų patogumui čia yra vienas kodas, esantis viename kodo fragmente:


Pastaba . Patogus būdas naudoti klases ir juos kompiliuoti „JavaScript“ yra „TypeScript“. Čia yra platforma, kurioje galite rasti keletą pavyzdžių, rodančių, kaip tai veikia. Net jei šiuo metu nenaudojate „TypeScript“, galite ieškoti, nes galite palyginti „TypeScript“ su „JavaScript“ rezultatais. Dauguma pavyzdžių yra paprasti, tačiau yra ir Raytracer pavyzdys, kurį galite iš karto išbandyti. Ypač rekomenduoju išnagrinėti pavyzdžių „Naudojimasis klasėmis“, „Naudojimasis paveldėjimu“ ir „Bendrasis naudojimas“, pasirinkdami juos kombinuotoje versijoje - tai gražūs šablonai, kuriuos galite iš karto naudoti „JavaScript“.

21
10 сент. atsakymas, kurį pateikė Matt Sep 10 2013-09-10 14:53 '13, 14:53 2013-09-10 14:53

Atnaujintas atsakymas:

ECMAScript 6 sistemoje galite sukurti statines funkcijas naudodami static :

 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 klasės nepateikia jokių naujų semantikos statikai. Tai galite padaryti ir ES5 taip:

 //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 

Galite priskirti „ Foo savybę, nes „JavaScript“ funkcijose yra objektų.

16
27 марта '15 в 4:09 2015-03-27 04:09 atsakymą pateikė Maxas Heiberis kovo 27 d. 15 val. 04:09 2015-03-27 04:09

Toliau pateikiamas pavyzdys ir paaiškinimas pateikiamas Nicholas Zako knygos 2-osios versijos „Profesionalus JavaScript“ knygoje. Tai yra atsakymas, kurio ieškojau, todėl maniau, kad būtų naudinga ją čia pridėti.

 (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 

Šiame pavyzdyje Person konstruktorius turi prieigą prie privataus kintamojo pavadinimo, taip pat getName() ir setName() metodų. Naudojant šį šabloną, vardo kintamasis tampa statinis ir bus naudojamas visais atvejais. Tai reiškia, kad skambinant į setName() vienoje instancijoje veikia visi kiti atvejai. setName() arba sukuriant naują „ Person egzempliorių, nustatoma naujos vertės vardo kintamoji. Dėl to visi atvejai grąžina tą pačią vertę.

13
13 дек. Atsakymas duotas Nate, gruodžio 13 d. 2011-12-13 11:26 '11 11:26 2011-12-13 11:26

Jei naudojate naują klasės sintaksę , galite atlikti šiuos veiksmus:

5
22 февр. atsakymas duotas „ Automatico“ vasario 22 d. 2017-02-22 19:11 '17 19:11 2017-02-22 19:11

Jei norite deklaruoti statinius kintamuosius, skirtus sukurti taikomąsias konstantas, kaip labiausiai supaprastintą metodą, aptikau šiuos duomenis

 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; 
4
03 апр. Hemant atsakymas, pateiktas balandžio 03 d 2013-04-03 01:05 '13, 1:05, 2013-04-03 01:05

Yra ir kitų panašių atsakymų, bet nė vienas iš jų man nepateikė. Štai ką baigiau:

 var nextCounter = (function () { var counter = 0; return function() { var temp = counter; counter += 1; return temp; }; })(); 
4
08 февр. atsakymas duotas linksmybei 08 февр . 2015-02-08 06:34 '15 at 6:34 am 2015-02-08 06:34

Galite sukurti statinį kintamąjį javascript'e, kaip parodyta žemiau. Čia yra statinis kintamasis.

 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 

Statinę kintamąjį galite priskirti naudodami Person funkciją arba bet kurį iš šių atvejų:

 // 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 
3
31 июля '16 в 9:16 2016-07-31 09:16 atsakymas duodamas Snađoshƒaӽ liepos 31 d. 16 val. 9:16 2016-07-31 09:16

Jei norite sukurti pasaulinį statinį kintamąjį:

 var my_id = 123; 

Pakeiskite kintamąjį taip:

 Object.defineProperty(window, 'my_id', { get: function() { return 123; }, configurable : false, enumerable : false }); 
3
16 марта '12 в 6:56 2012-03-16 06:56 atsakymą JoolzCheat pateikė kovo 16 d. 12 val. 6:56 2012-03-16 06:56

Apie ECMAScript 2015 pateiktą class . Kiti atsakymai nėra visiškai aiškūs.

Štai pavyzdys, rodantis, kaip sukurti statinį var staticVar naudojant staticVar . var synthax:

 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 

Norėdami pasiekti statinį kintamąjį, mes naudojame .constructor savybę, kuri grąžina nuorodą į objekto konstruktorių, kuris sukūrė klasę. Galime jį skambinti dviem sukurtais atvejais:

 MyClass.staticVar = 11; console.log(class1.constructor.staticVar); // 11 console.log(class2.constructor.staticVar); // 11 <-- yes it static! :) MyClass.staticVar = 12; console.log(class1.constructor.staticVar); // 12 console.log(class2.constructor.staticVar); // 12 
3
24 марта '17 в 13:02 2017-03-24 13:02 atsakymą pateikė COil kovo 24 d. 17 d. 13:02 2017-03-24 13:02

Artimiausias dalykas, kai „JavaScript“ skirtas statiniam kintamajam, yra pasaulinis kintamasis - tai tik kintamasis, deklaruotas už funkcijos ar objekto ribos ribų:

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

Kitas dalykas, kurį galėtumėte padaryti, yra išsaugoti pasaulinius kintamuosius objekto raidės viduje taip:

 var foo = { bar : 1 } 

Ir tada pasiekite tokius kintamuosius: foo.bar .

2
08 окт. atsakymas Andrew Hare 08 spalis 2009-10-08 07:33 '09, 7:33 am. 2009-10-08 07:33

Numatytieji „JavaScript“ kintamieji yra statiniai . Pavyzdys:

 var x = 0; funkcijos piešinys () { įspėjimas (x);  // x + = 1; } setInterval (piešti, 1000);

X vertė padidinama 1 kartą per 1000 milisekundžių.
Jis spausdins 1,2,3 ir daugiau.

2
08 апр. atsakymą pateikė Kerim 08 balandžio. 2017-04-08 15:39 '17, 13:39 pm 2017-04-08 15:39

Jei norite sutrumpinti visas klasės sąvokas, patikrinkite:

 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 

Na, dar vienas būdas pažvelgti į geriausias praktikas šiuose dalykuose yra tik pamatyti, kaip coffeescript verčia šias sąvokas.

 #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); 
2
24 нояб. atsakymą pateikė Stratboy lapkričio 24 d. 2013-11-24 14:20 '13, 14:20 pm 2013-11-24 14:20

Po to, kai peržiūrėjau šią temą, buvo priimtas kitoks požiūris, kuris nustatė mano reikalavimus. Tai priklauso nuo to, ką norite pasiekti „statiniu kintamuoju“.

Pasaulinė sesijaStorage arba localStorage ypatybė leidžia saugoti duomenis sesijos metu arba neribotą laiką, kol ji bus aiškiai išvalyta. Tai leidžia dalytis duomenimis tarp visų >

Jis vengia visų problemų, susijusių su aprėpties, gyvenimo trukme, semantika, dinamika ir kt. pasauliniai aukščiausio lygio kintamieji, t. y. „Window.myglobal“ Nežinau, kaip tai yra veiksminga, bet tai nėra svarbu nedideliems duomenų kiekiams, prie kurių prieinama nedideliais tarifais.

Lengva pasiekti kaip „sessionStorage.mydata = nieko“ ir gauti taip pat. Žr. „JavaScript: galutinis vadovas, šeštasis leidimas“, Davidas Flanaganas, ISBN: 978-0-596-80552-4, 20 skyriaus 20.1 skirsnis. Tai lengva atsisiųsti PDF formatu paprasta paieška arba prenumerata „O'Reilly Safaribooks“ (verta jos svorio aukso).

Sveikinimai, Greg E

2
07 апр. Atsakyti Greg E 07 Bal 2013-04-07 12:58 '13, 12:58, 2013-04-07 12:58
08 окт. Atsakymas duotas Bostone 08 okt. 2009-10-08 07:34 '09 7:34 am. 2009-10-08 07:34

Jei norite naudoti prototipą, tai yra būdas

 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); 

Tokiu būdu galite prieiti prie skaitiklių kintamojo bet kuriuo atveju, o bet kokie turto pakeitimai bus nedelsiant atspindėti!

0
09 мая '14 в 9:25 2014-05-09 09:25 atsakymą pateikė charlie gegužės 09 '14, 9:25 2014-05-09 09:25

„JavaScript“ sistemoje nėra jokių statinių terminų ar raktinių žodžių, tačiau tokius duomenis galime tiesiogiai įdėti į funkcijų objektą (kaip ir bet kurį kitą objektą).

 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 
0
31 марта '16 в 20:44 2016-03-31 20:44 atsakymą pateikė Satyapriya Mishra kovo 31 d. 16:44 2016-03-31 20:44

Privatiems statiniams kintamiesiems šį metodą nustatiau:

 function Class() { } Class.prototype = new function() { _privateStatic = 1; this.get = function() { return _privateStatic; } this.inc = function() { _privateStatic++; } }; var o1 = new Class(); var o2 = new Class(); o1.inc(); console.log(o1.get()); console.log(o2.get()); // 2 
0
25 окт. Martin Wantke atsakymas, spalio 25 d 2016-10-25 15:42 '16 at 15:42 2016-10-25 15:42

Taigi, su kitais atsakymais matau, kad jie neatsižvelgia į esminį statinio atributo architektūrinį reikalavimą į objektą orientuotame programavime.