JavaScriptで静的変数を作成するにはどうすればよいですか?
someFunc = () => { MyClass.myStaticVariable = 1; }
ます。次に、静的メソッドを作成して静的メンバーを返しstatic getStatic() { return MyClass.myStaticVariable; }
ます。次にMyClass.getStatic()
、クラスの外側から呼び出して静的データを取得できます。
JavaScriptで静的変数を作成するにはどうすればよいですか?
someFunc = () => { MyClass.myStaticVariable = 1; }
ます。次に、静的メソッドを作成して静的メンバーを返しstatic getStatic() { return MyClass.myStaticVariable; }
ます。次にMyClass.getStatic()
、クラスの外側から呼び出して静的データを取得できます。
回答:
クラスベースの静的型付きオブジェクト指向言語(Java、C ++、C#など)を使用している場合、インスタンスではなく「型」に関連付けられた変数またはメソッドを作成しようとしていると思います。
コンストラクター関数を使用した「クラシック」アプローチを使用した例は、基本的なOO JavaScriptの概念を理解するのに役立つ可能性があります。
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
MyClassオブジェクト(関数)で定義され、作成されたインスタンスとは何の関係もありません。JavaScriptは関数をファーストクラスオブジェクトとして扱うため、オブジェクトであり、プロパティを関数に割り当てることができます。
更新: ES6では、キーワードを使用してクラスを宣言する機能が導入されましたclass
。これは、既存のプロトタイプベースの継承に対する構文糖衣です。
static
キーワードは、あなたが簡単にクラスの静的プロパティやメソッドを定義することができます。
ES6クラスで実装された上記の例を見てみましょう:
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"
privilegedMethod
それはMyClassのインスタンスで呼び出すことができようにそれはそうなのでOOでプライベートメソッドと等価ではないでしょうか?アクセスできるので特権があるということですprivateVariable
か?
this.constructor
「インスタンスメソッド」から静的変数にアクセスするために使用できませんか?はいの場合は、回答に追加する価値があります。
MyClass.prototype.staticProperty = "baz";
か、OOの原則に対してさらに正確にするために、静的プロパティは実際には無名関数として定義する必要がありMyClass.prototype.staticProperty = function () {return staticVar;}
、すべてのインスタンスが1つの変数にアクセスできるようにします。
JS関数もオブジェクトであるという事実を利用するかもしれません-つまり、それらはプロパティを持つことができます。
例えば、上で与えられた例を引用記事(現在は消滅し)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);
}
その関数を数回呼び出すと、カウンターが増加していることがわかります。
そして、これはおそらく、グローバル変数でグローバル名前空間を汚染するよりもはるかに優れたソリューションです。
そして、これはクロージャに基づく別の可能な解決策です:JavaScriptで静的変数を使用するトリック:
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.
これにより、同じ種類の結果が得られます。ただし、今回は、表示されるのではなく、増分された値が返されます。
countMyself.counter = countMyself.counter || initial_value;
静的変数がfalse(false、0、null、または空の文字列)にならない場合にのみ実行できます
===
しtypeof
ないと、変な強制が行われます。
arguments.calleeを使用して「静的」変数を保存できます(これは無名関数でも役立ちます):
function () {
arguments.callee.myStaticVar = arguments.callee.myStaticVar || 1;
arguments.callee.myStaticVar++;
alert(arguments.callee.myStaticVar);
}
arguments.callee
廃止予定です。
callee
持つのは良いことのように思えました。なぜハックはこれを廃止することにしたのか...:|
似たような回答をいくつか見ましたが、この投稿がそれを最もよく表していることを述べたいので、それを共有したいと思います。
これから抜粋したコードの一部を以下に示します。これは、クラスのデザインテンプレートとして使用できるため、コミュニティに利益をもたらすと期待される完全な例を取得するために変更しました。
それはまたあなたの質問に答えます:
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 + ' ...');
};
この例では、次のように静的プロパティ/関数にアクセスできます。
// access static properties/functions
console.log(Podcast.FILE_EXTENSION); // 'mp3'
Podcast.download('Astronomy cast'); // 'Downloading Astronomy cast ...'
そして、オブジェクトのプロパティ/関数は単に次のようになります:
// access object properties/functions
var podcast = new Podcast();
podcast.title = 'The Simpsons';
console.log(podcast.toString()); // Title: The Simpsons
console.log(podcast.immutableProp()); // 123
注そのpodcast.immutablePropで()、我々はクロージャを: _somePrivateVariableへの参照は、関数の内部で保持されます。
ゲッターとセッターを定義することもできます。次のコードスニペットを見てください(d
プロパティを宣言するオブジェクトのプロトタイプy
は、コンストラクターの外部からは見えないプライベート変数です)。
// getters and setters
var d = Date.prototype;
Object.defineProperty(d, "year", {
get: function() {return this.getFullYear() },
set: function(y) { this.setFullYear(y) }
});
プロパティはd.year
via get
とset
関数を定義します-を指定しない場合set
、プロパティは読み取り専用で変更できません(設定しようとしてもエラーは発生しませんが、効果はありません)。各プロパティには属性がありwritable
、configurable
(宣言の後に変更することができます)とenumerable
、デフォルトごとにある(列挙子としてそれを使用できるようにします)、 false
。これらdefineProperty
は、3番目のパラメータ(など)で設定できますenumerable: true
。
次の構文も有効です。
// getters and setters - alternative syntax
var obj = { a: 7,
get b() {return this.a + 1;},
set c(x) {this.a = x / 2}
};
これは、読み取り/書き込み可能なプロパティa
、読み取り専用プロパティb
、および書き込み専用プロパティを定義します。c
これらのプロパティを通じてa
アクセスできます。
使用法:
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
ノート:
new
キーワードを忘れた場合の予期しない動作を回避するために、関数に以下を追加することをお勧めしますPodcast
。
// instantiation helper
function Podcast() {
if(false === (this instanceof Podcast)) {
return new Podcast();
}
// [... same as above ...]
};
これで、次のインスタンス化の両方が期待どおりに機能します。
var podcast = new Podcast(); // normal usage, still allowed
var podcast = Podcast(); // you can omit the new keyword because of the helper
'new'ステートメントは、新しいオブジェクトを作成し、すべてのプロパティとメソッドをコピーします。
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"
また、状況によってreturn
は、コンストラクター関数のステートメントを使用してPodcast
、クラスが内部的に依存しているが公開する必要のある関数を保護するカスタムオブジェクトを返すと便利な場合があります。これについては、一連の記事の第2章(オブジェクト)で詳しく説明しています。
あなたはそれを言ってa
、b
から継承することができますPodcast
。さて、何をした後、それらのすべてに適用されるポッドキャストへのメソッドを追加したい場合a
やb
インスタンス化されていますか?この場合、.prototype
次のように使用します。
Podcast.prototype.titleAndLink = function() {
return this.title + " [" + this.link + "]";
};
今すぐお電話a
とb
再び:
console.log(a.titleAndLink()); // "a [http://www.astronomycast.com]"
console.log(b.titleAndLink()); // "An Astronomy Cast [http://www.astronomycast.com]"
プロトタイプの詳細については、こちらをご覧ください。より多くの継承をしたい場合は、これを調べることをお勧めします。
上記の記事シリーズは、読むことを強くお勧めします。次のトピックも含まれます。
JavaScriptのセミコロン自動挿入「機能」(6で説明)は、コードで奇妙な問題を引き起こす原因となることが非常に多いことに注意してください。したがって、私はむしろそれを機能としてではなくバグと見なしたいと思います。
あなたがもっと読みたい場合は、ここでは非常に興味深いですMSDNの記事これらのトピックについて、それらのいくつかは、さらに多くの詳細が提供説明しました。
同じく興味深いのは(上記のトピックもカバーする)MDN JavaScriptガイドの記事です:
JavaScriptで(など)c#out
パラメーターをエミュレートする方法を知りたい場合はDateTime.TryParse(str, out result)
、ここでサンプルコードを見つけることができます。
されているあなたの人々のIEでの作業(あなたが使用して開発ツールを開かない限りはJavaScriptのためのコンソールを持っていないF12し、コンソールタブを開くには)次のスニペットが役に立つかもしれません。console.log(msg);
上記の例で使用されているように使用できます。Podcast
関数の前に挿入するだけです。
便宜上、上記のコードを1つの完全な単一のコードスニペットで示します。
ノート:
JavaScriptプログラミング全般に関するいくつかの優れたヒント、ヒント、および推奨事項は、ここ(JavaScriptのベストプラクティス)とそこ(「var」と「let」)にあります。暗黙の型キャスト(強制)に関するこの記事もお勧めし ます。
クラスを使用してJavaScriptにコンパイルする便利な方法はTypeScriptです。 遊び場は、それがどのように機能するかを示すいくつかの例を見つけることができます。現時点でTypeScriptを使用していない場合でも、TypeScriptとJavaScriptの結果を並べて表示して比較できるので、外観を確認できます。ほとんどの例は単純ですが、すぐに試すことができるレイトレーサーの例もあります。特に、「クラスの使用」、「継承の使用」、および「ジェネリックスの使用」の例をコンボボックスで選択して調べることをお勧めします。これらは、JavaScriptですぐに使用できる素晴らしいテンプレートです。TypescriptはAngularで使用されます。
達成するためにカプセル化ローカル変数は、JavaScriptの関数などのを、私は(jQueryのと同じ手法を使用しています)、次のようなパターンを使用することをお勧め:
<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 method
var _main = function(title) {
if (title !== undefined) print(title);
print("<b>last modified: </b>" + context.document.lastModified + "<br/>");
// ... more code ...
}
// public methods
return {
Main: _main
// ... more public methods, properties ...
};
})(this);
// use module
myModule.Main("<b>Module demo</b>");
</script></body>
</html>
もちろん、スクリプトコードを別の*.js
ファイルに配置することもできます。これは、例を短くするためにインラインで書かれているだけです。
自己呼び出し関数(IIFE =即時呼び出し関数式とも呼ばれます)については、ここで詳しく説明します。
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();
更新された回答:
ECMAScript 6、あなたが使用してスタティック関数を作成することができます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クラスは、静的の新しいセマンティクスを導入しません。ES5では次のように同じことができます。
//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
Foo
JavaScriptでは関数はオブジェクトなので、プロパティに割り当てることができます。
bar
の財産Foo
にし3
、次のように:Foo.bar = 3;
次の例と説明は、Nicholas Zakas著の本「Professional JavaScript for Web Developers 2nd Edition」から引用しています。これが私が探していた答えなので、ここに追加すると役立つと思いました。
(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
Person
この例のコンストラクタは、getName()
およびsetName()
メソッドと同様に、プライベート変数名にアクセスできます。このパターンを使用すると、name変数が静的になり、すべてのインスタンス間で使用されます。つまりsetName()
、1つのインスタンスを呼び出すと、他のすべてのインスタンスに影響します。setName()
新しいPerson
インスタンスを呼び出すか作成すると、name変数に新しい値が設定されます。これにより、すべてのインスタンスが同じ値を返します。
新しいクラス構文を使用している場合は、次の操作を実行できます。
class MyClass {
static get myStaticVariable() {
return "some static variable";
}
}
console.log(MyClass.myStaticVariable);
aMyClass = new MyClass();
console.log(aMyClass.myStaticVariable, "is undefined");
これにより、JavaScriptで静的変数が効果的に作成されます。
MyClass
、クラスコンストラクトの外部で定義されたプロパティが必要になります。
class
ECMAScript 2015によって導入されたものについて。他の答えは完全に明確ではありません。
ここでは、静的VAR作成する方法を示す例であるstaticVar
としますClassName
。var
シンタックス:
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
静的変数にアクセスするには、 .constructor
、クラスを作成したオブジェクトコンストラクター関数への参照を返すプロパティます。作成した2つのインスタンスで呼び出すことができます。
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
残りに加えて、クラスにパブリックフィールドを紹介するECMAプロポーザルに関するドラフト(ステージ2プロポーザル)が現在あります。(プライベートフィールドが考慮されましたstatic
)
提案の例を使用すると、提案されるstatic
構文は次のようになります。
class CustomDate {
// ...
static epoch = new CustomDate(0);
}
そして、他の人が強調した以下のものと同等です:
class CustomDate {
// ...
}
CustomDate.epoch = new CustomDate(0);
その後、からアクセスできますCustomDate.epoch
。
で新しい提案を追跡できproposal-static-class-features
ます。
現在、babelは、使用できる変換クラスプロパティプラグインでこの機能をサポートしています。さらに、まだ進行中V8
ですが、実装しています。
以下のようにJavaScriptで静的変数を作成できます。これcount
が静的変数です。
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
Person
関数またはインスタンスのいずれかを使用して、静的変数に値を割り当てることができます。
// 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
グローバル静的変数を作成したい場合:
var my_id = 123;
変数を以下に置き換えます。
Object.defineProperty(window, 'my_id', {
get: function() {
return 123;
},
configurable : false,
enumerable : false
});
JavaScriptで静的変数に最も近いのはグローバル変数です。これは、関数またはオブジェクトリテラルのスコープ外で宣言された変数です。
var thisIsGlobal = 1;
function foo() {
var thisIsNot = 2;
}
他にできることは、次のようなオブジェクトリテラル内にグローバル変数を格納することです。
var foo = { bar : 1 }
次に、次のように変数にアクセスしますfoo.bar
。
ここでクラスのすべての概念を要約するには、これをテストします。
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
そうですね、これらのベストプラクティスを確認するもう1つの方法は、coffeescriptがこれらの概念をどのように変換するかを確認することです。
#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);
このスレッドを閲覧した後、私の要件を解決する別のアプローチがあります。それは、「静的変数」で何を実現したいかによります。
グローバルプロパティのsessionStorageまたはlocalStorageを使用すると、セッションの存続期間中、または明示的にクリアされるまで、無期限に長期間データを保存できます。これにより、ページ/アプリのすべてのウィンドウ、フレーム、タブパネル、ポップアップなどでデータを共有できるようになり、1つのコードセグメントの単純な「静的/グローバル変数」よりもはるかに強力になります。
これは、トップレベルのグローバル変数、つまりWindow.myglobalのスコープ、有効期間、セマンティクス、ダイナミクスなどの面倒をすべて回避します。それがどれほど効率的であるかはわかりませんが、適度な速度でアクセスされる適度な量のデータにとっては重要ではありません。
「sessionStorage.mydata = Anything」として簡単にアクセスでき、同様に取得できます。「JavaScript:The Definitive Guide、Sixth Edition」、David Flanagan、ISBN:978-0-596-80552-4、第20章、セクション20.1を参照してください。これは、簡単な検索でPDFとして、またはO'Reilly Safaribooksサブスクリプション(金でその価値があります)で簡単にダウンロードできます。
関数の/クラスは、そのオブジェクトスコープに対して単一のコンストラクターのみを許可します。
Function Hoisting, declarations & expressions
Functionコンストラクターで作成された関数は、作成コンテキストにクロージャーを作成しません。それらは常にグローバルスコープで作成されます。
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)
クロージャ -クロージャのコピーは、データが保持された機能です。
- 各クロージャーのコピーは、独自の空き値または参照を持つ関数に作成されます。別の関数内で関数を使用する場合は常に、クロージャーが使用されます。
JavaScriptでのクロージャーは、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関数クラス:Object.defineProperty(O、P、属性)を使用します
Object.defineProperty()メソッドは、オブジェクトに直接新しいプロパティを定義し、またはオブジェクト上の既存のプロパティを変更し、オブジェクトを返します。
``を使用していくつかのメソッドを作成し、関数クラスを簡単に理解できるようにしました。
'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;
}
以下のコードスニペットは、各インスタンスがインスタンスメンバーと共通の静的メンバーの独自のコピーを持つかどうかをテストするためのものです。
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
静的メソッドの呼び出しはクラスで直接行われ、クラスのインスタンスでは呼び出すことができません。ただし、インスタンス内から静的メンバーの呼び出しを実行できます。
構文を使用:
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クラス:ES2015クラスは、プロトタイプベースのOOパターンに対する単純な砂糖です。単一の便利な宣言型フォームを使用すると、クラスパターンが使いやすくなり、相互運用性が向上します。クラスは、プロトタイプベースの継承、スーパーコール、インスタンスおよび静的メソッドとコンストラクタをサポートします。
例:以前の投稿を参照してください。
JavaScriptで関数ローカルの静的変数をエミュレートするには、4つの方法があります。
方法1:関数オブジェクトのプロパティを使用する(古いブラウザーでサポートされていました)
function someFunc1(){
if( !('staticVar' in someFunc1) )
someFunc1.staticVar = 0 ;
alert(++someFunc1.staticVar) ;
}
someFunc1() ; //prints 1
someFunc1() ; //prints 2
someFunc1() ; //prints 3
方法2:クロージャーを使用する、バリアント1(古いブラウザーでサポート)
var someFunc2 = (function(){
var staticVar = 0 ;
return function(){
alert(++staticVar) ;
}
})()
someFunc2() ; //prints 1
someFunc2() ; //prints 2
someFunc2() ; //prints 3
方法3:クロージャーのバリアント2を使用(古いブラウザーでもサポート)
var someFunc3 ;
with({staticVar:0})
var someFunc3 = function(){
alert(++staticVar) ;
}
someFunc3() ; //prints 1
someFunc3() ; //prints 2
someFunc3() ; //prints 3
方法4:クロージャーを使用する、バリアント3(EcmaScript 2015のサポートが必要)
{
let staticVar = 0 ;
function someFunc4(){
alert(++staticVar) ;
}
}
someFunc4() ; //prints 1
someFunc4() ; //prints 2
someFunc4() ; //prints 3
次のキーワードを使用して、JavaScriptで静的関数を定義できますstatic
。
class MyClass {
static myStaticFunction() {
return 42;
}
}
MyClass.myStaticFunction(); // 42
この記事を書いている時点では、クラス内で(関数以外の)静的プロパティを定義することはできません。静的プロパティはまだステージ3の提案です。つまり、静的プロパティはまだJavaScriptの一部ではありません。ただし、他のオブジェクトと同じように、単にクラスに割り当てることを妨げるものは何もありません。
class MyClass {}
MyClass.myStaticProperty = 42;
MyClass.myStaticProperty; // 42
最後の注意:継承を伴う静的オブジェクトの使用には注意してください。継承されたすべてのクラスは、オブジェクトの同じコピーを共有します。
JavaScriptには静的な用語やキーワードはありませんが、そのようなデータを(他のオブジェクトと同様に)関数オブジェクトに直接入れることができます。
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
私は静的関数変数を頻繁に使用していますが、これはJSにそのための組み込みメカニズムがないのは残念です。変数と関数が1つの関数内で使用されているだけでも、外部スコープで定義されているコードを頻繁に目にします。これは醜く、エラーが発生しやすく、問題を尋ねるだけです...
私は次の方法を思いつきました:
if (typeof Function.prototype.statics === 'undefined') {
Function.prototype.statics = function(init) {
if (!this._statics) this._statics = init ? init() : {};
return this._statics;
}
}
これは、すべての関数に「静的」メソッドを追加します(そう、それについてリラックスするだけです)。呼び出されると、関数オブジェクトに空のオブジェクト(_statics)が追加され、それが返されます。init関数が指定されている場合、_staticsはinit()の結果に設定されます。
その後、次のことができます。
function f() {
const _s = f.statics(() => ({ v1=3, v2=somefunc() });
if (_s.v1==3) { ++_s.v1; _s.v2(_s.v1); }
}
これを他の正解であるIIFEと比較すると、これには、関数呼び出しごとに1つの代入と1つの代入を追加し、関数に「_statics」メンバーを追加するという欠点がありますが、いくつかの利点があります。引数は内部関数コードでは 'static'を使用しているため、内部関数にないトップは '_s'で明示されます。接頭辞、そしてそれを見て理解することは全体的に簡単です。
ではES6
/ ES 2015 class
キーワードが伴って導入されたstatic
キーワード。これは、javavscriptが具現化するプロトタイプの継承モデルに対する構文上の砂糖であることを覚えておいてください。static
キーワードは、方法については、以下のように動作します。
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);
Javascriptには静的変数などはありません。この言語はプロトタイプベースのオブジェクト指向であるため、クラスはありませんが、オブジェクトが自分自身を「コピー」する場所からのプロトタイプがあります。
グローバル変数またはプロトタイピング(プロトタイプにプロパティを追加)でそれらをシミュレートできます。
function circle(){
}
circle.prototype.pi=3.14159
Function.prototype
function circle() {}
| circle.prototype
| circle.prototype.pi = 3.14
| circle.prototype
| Function.prototype
| Function.__proto__
(それがあなたが意図したものである場合)
jQueryを使用するMVC Webサイトを使用して、特定のイベントハンドラー内のAJAXアクションが、前のリクエストが完了した後にのみ実行できることを確認したいです。これを実現するには、「静的」jqXHRオブジェクト変数を使用します。
次のボタンがあるとします:
<button type="button" onclick="ajaxAction(this, { url: '/SomeController/SomeAction' })">Action!</button>
私は通常、クリックハンドラーに次のようなIIFEを使用します。
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);
プロトタイプを使用したい場合は、方法があります
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);
これを行うと、任意のインスタンスからカウンター変数にアクセスでき、プロパティの変更がすぐに反映されます。