JavaScript変数のスコープとメモリ問題の実例分析
8106 ワード
本論文の実例はJavaScript変数のスコープおよびメモリの問題を述べている。皆さんに参考にしてあげます。具体的には以下の通りです。
学習のポイント:
1.変数とスコープ
2.メモリ問題
JavaScriptの変数は他の言語の変数とは大きな違いがあります。JavaScript変数は、フリータイプの本質であり、特定の時間に特定の値を保存するための名前だけを決定します。変数を定義するルールがないので、変数の値とデータの種類はシナリオのライフサイクル内で変更できます。
一.変数とスコープ
1.基本タイプと参照タイプの値
ECMAScript変数は、2つの異なるデータタイプの値を含むことができます。基本タイプの値と参照タイプの値です。基本タイプの値とは、スタックメモリに保存されている簡単なデータセグメント、すなわちこの値がメモリに完全に保存されている場所のことです。参照タイプの値は、メモリに保存されているオブジェクトを意味します。変数に保存されているのは実際にはポインタだけで、このポインタはメモリの別の位置を指し、オブジェクトを保存します。
一つの値を変数に割り当てる場合は、この値がベースタイプの値か、参照タイプの値かを判定しなければなりません。基本タイプの値は以下の通りです。Udefined、Null、Boolean、Number、String。これらのタイプはメモリの中でそれぞれ固定サイズの空間を占有しています。彼らの値はスタックの空間に保存されています。私たちは値によって訪問します。
PS:いくつかの言語では、文字列は対象として表されていますので、参照の種類とされています。ECMAScriptはこの伝統を放棄します。
参照タイプの値が割り当てられている場合は、この値のためにヒープメモリに空間を割り当てる必要があります。この値の大きさは固定されていないので、スタックメモリに保存することはできません。ただし、メモリアドレスのサイズが固定されているため、メモリアドレスをスタックメモリに保存することができます。このように、参照型の変数を照会するときは、まずスタックからメモリアドレスを読み出してから、アドレスを介してスタックの値を探します。このように、私たちはそれを引用訪問と呼びます。
2.ダイナミック属性
基本型の値と参照型の値を定義する方法は似ています。変数を作成し、変数に値を割り当てます。しかし、この値が変数に保存されると、異なるタイプの値に対して実行できる操作は大きく異なります。
変数コピーでは、基本タイプと参照タイプが異なります。基本タイプは値自体をコピーし、参照タイプはアドレスをコピーします。
4.伝達パラメータ
ECMAScriptのすべての関数のパラメータは値によって伝達されます。つまり、パラメータは参照によって伝達されません。変数には基本的なタイプと参照タイプの区別がありますが。
以下に、参照タイプの例としてパラメータを示します。
PS:だから引用伝達と伝達引用の種類によって2つの異なる概念です。
5.検出タイプ
変数のタイプを検出するには、
この時は
5.実行環境とスコープ
実行環境はJavaScriptの中で最も重要な概念です。実行環境は、変数や関数がアクセスできる他のデータを定義し、それぞれの挙動を決定します。
グローバル実行環境は、最も周辺的な実行環境である。Webブラウザでは、グローバル実行環境はwindowオブジェクトとして認識されている。したがって、すべての大域変数と関数は、windowオブジェクトの属性と方法として作成されます。
PS:各実行環境には関連する変数オブジェクトがあります。例えばグローバルのwindowで変数と属性を呼び出すことができます。ローカル環境にもWindowsのような変数オブジェクトがあります。環境で定義されているすべての変数と関数はこのオブジェクトに保存されます。この変数のオブジェクトにアクセスできませんでしたが、データを処理するときにはバックグラウンドで使います。
関数内の局所作用領域の変数は大域変数に置換されますが、作用領域は関数内のこの局所環境に限られます。
PS:コードが一つの環境で実行されると、作用ドメインチェーンというものが形成されます。その用途は、実行環境におけるアクセス権限のある変数と関数の秩序的なアクセスを保証することです。作用するドメインチェーンの先端は、環境を実行する変数のオブジェクトです。
6.ブロックレベルのスコープがない
ブロックレベルのスコープは、if文などの括弧が閉じられたコードブロックを表しているので、変数を定義するために条件判定をサポートします。
一般的に、変数は検索によって、その識別子が実際に何を表すかを決定する。
二.メモリ問題
JavaScriptは自動ごみ収集機構を持っています。つまり、実行環境はコードの実行中に使用されるメモリを管理します。その他の言語はCとC++、手でメモリの使用状況を追跡しなければなりません。タイムリーなリリースは多くの問題を引き起こします。JavaScriptはこのようにする必要がなくて、それは自分でメモリの分配と不要なメモリの回収を管理することができます。
JavaScriptで最もよく使われているごみの収集方法はマーククリアです。ゴミ収集器は、実行時にメモリに格納されている変数にマークを付けます。次に、環境で使用されている変数のマークを削除します。マークが削除されていない変数は、削除を準備している変数と見なされます。最後に、ごみ収集器はメモリの整理作業を完了し、マーク付きの値を廃棄し、彼らが使っているメモリ空間を回収します。
ゴミ収集器は周期的に運行しています。このようにプログラム全体の性能問題が発生します。例えば、IE 7の以前のバージョンでは、そのごみ収集器はメモリ割り当て量によって運行されています。例えば、256個の変数がゴミ収集器を実行し始めます。このように、頻繁に運行しなければならないので、性能が低下します。
一般的に、最小のメモリを占有することで、ページがより良い性能を得ることができることを保証する。メモリを最適化する最善の方法は、いったんデータが役に立たなくなると、nullに設定して参照を解放することです。この方法はほとんどのグローバル変数とグローバルオブジェクトに適用されます。
本論文で述べたように、JavaScriptプログラムの設計に役に立ちます。
学習のポイント:
1.変数とスコープ
2.メモリ問題
JavaScriptの変数は他の言語の変数とは大きな違いがあります。JavaScript変数は、フリータイプの本質であり、特定の時間に特定の値を保存するための名前だけを決定します。変数を定義するルールがないので、変数の値とデータの種類はシナリオのライフサイクル内で変更できます。
一.変数とスコープ
1.基本タイプと参照タイプの値
ECMAScript変数は、2つの異なるデータタイプの値を含むことができます。基本タイプの値と参照タイプの値です。基本タイプの値とは、スタックメモリに保存されている簡単なデータセグメント、すなわちこの値がメモリに完全に保存されている場所のことです。参照タイプの値は、メモリに保存されているオブジェクトを意味します。変数に保存されているのは実際にはポインタだけで、このポインタはメモリの別の位置を指し、オブジェクトを保存します。
一つの値を変数に割り当てる場合は、この値がベースタイプの値か、参照タイプの値かを判定しなければなりません。基本タイプの値は以下の通りです。Udefined、Null、Boolean、Number、String。これらのタイプはメモリの中でそれぞれ固定サイズの空間を占有しています。彼らの値はスタックの空間に保存されています。私たちは値によって訪問します。
PS:いくつかの言語では、文字列は対象として表されていますので、参照の種類とされています。ECMAScriptはこの伝統を放棄します。
参照タイプの値が割り当てられている場合は、この値のためにヒープメモリに空間を割り当てる必要があります。この値の大きさは固定されていないので、スタックメモリに保存することはできません。ただし、メモリアドレスのサイズが固定されているため、メモリアドレスをスタックメモリに保存することができます。このように、参照型の変数を照会するときは、まずスタックからメモリアドレスを読み出してから、アドレスを介してスタックの値を探します。このように、私たちはそれを引用訪問と呼びます。
2.ダイナミック属性
基本型の値と参照型の値を定義する方法は似ています。変数を作成し、変数に値を割り当てます。しかし、この値が変数に保存されると、異なるタイプの値に対して実行できる操作は大きく異なります。
var box = new Object(); //
box.name = 'Lee'; //
alert(box.name); //
基本タイプの値に属性を付けると問題が発生します。
var box = 'Lee'; //
box.age = 27; //
alert(box.age); //undefined
3.変数値のコピー変数コピーでは、基本タイプと参照タイプが異なります。基本タイプは値自体をコピーし、参照タイプはアドレスをコピーします。
var box = 'Lee'; // box 'Lee'
var box2 = box; // box2 'Lee'
box 2は、box 1のコピーですが、図からは完全に独立していることが分かります。つまり、2つの変数が別々に操作されても互いに影響がありません。
var box = new Object(); //
box.name = 'Lee'; //
var box2 = box; // box2
引用のタイプでは、box 2は実はboxです。彼らは同じ対象を指しています。このオブジェクトのname属性が修正されたら、box 2.nameとbox.nameの出力値はそれぞれ修正されます。4.伝達パラメータ
ECMAScriptのすべての関数のパラメータは値によって伝達されます。つまり、パラメータは参照によって伝達されません。変数には基本的なタイプと参照タイプの区別がありますが。
function box(num) { // ,
num += 10; // num ,
return num;
}
var num = 50;
var result = box(num);
alert(result); //60
alert(num); //50
PS:以上のコードの中で、伝達パラメータは基本タイプの値です。関数のnumは局所変数で、外のnumとは何の関係もありません。以下に、参照タイプの例としてパラメータを示します。
function box(obj) { // ,
obj.name = 'Lee';
}
var p = new Object();
box(p);
alert(p.name);
PS:参照によって伝達される変数があれば、関数内のその変数はグローバル変数となり、外部からもアクセスできます。たとえばPHPでは、パラメータの前に&符号を付けて参照によって伝達しなければなりません。ECMAScriptはこれらがなくて、局部変数だけです。PHPで調べられます。PS:だから引用伝達と伝達引用の種類によって2つの異なる概念です。
function box(obj) {
obj.name = 'Lee';
var obj = new Object(); //
obj.name = 'Mr.'; // obj
}
最後に結論を出しました。ECMAScript関数のパラメータは局所変数、つまり、引用伝達されませんでした。5.検出タイプ
変数のタイプを検出するには、
typeof
演算子で判別できます。たとえば:
var box = 'Lee';
alert(typeof box); //string
typeof演算子は基本的なデータの種類をチェックする時にとても使いやすいですが、参照の種類を検出する時には、あまり使いやすくありません。通常、私たちは相手ではなく、どのタイプのオブジェクトなのかを知りたいです。配列もobjectなので、nullもObjectなどです。この時は
instanceof
の演算子を使って調べます。
var box = [1,2,3];
alert(box instanceof Array); //
var box2 = {};
alert(box2 instanceof Object); //
var box3 = /g/;
alert(box3 instanceof RegExp); //
var box4 = new String('Lee');
alert(box4 instanceof String); //
PS:instance ofを使ってベースタイプの値をチェックすると、falseに戻ります。5.実行環境とスコープ
実行環境はJavaScriptの中で最も重要な概念です。実行環境は、変数や関数がアクセスできる他のデータを定義し、それぞれの挙動を決定します。
グローバル実行環境は、最も周辺的な実行環境である。Webブラウザでは、グローバル実行環境はwindowオブジェクトとして認識されている。したがって、すべての大域変数と関数は、windowオブジェクトの属性と方法として作成されます。
var box = 'blue'; //
function setBox() {
alert(box); //
}
setBox(); //
大域の変数と関数は、すべてwindowオブジェクトの属性と方法です。
var box = 'blue';
function setBox() {
alert(window.box); // window
}
window.setBox(); // window
PS:実行環境にあるコードのすべてが実行された後、この環境は破壊され、保存されている変数と関数の定義も廃棄されました。グローバル環境の場合は、プログラムの実行が完了したり、ウェブページが閉じられたりして廃棄されます。PS:各実行環境には関連する変数オブジェクトがあります。例えばグローバルのwindowで変数と属性を呼び出すことができます。ローカル環境にもWindowsのような変数オブジェクトがあります。環境で定義されているすべての変数と関数はこのオブジェクトに保存されます。この変数のオブジェクトにアクセスできませんでしたが、データを処理するときにはバックグラウンドで使います。
関数内の局所作用領域の変数は大域変数に置換されますが、作用領域は関数内のこの局所環境に限られます。
var box = 'blue';
function setBox() {
var box = 'red'; // ,
alert(box);
}
setBox();
alert(box);
参照によって関数内の局所変数を置き換えることができますが、作用領域は関数内のこの局所環境に限定されます。
var box = 'blue';
function setBox(box) { // ,
alert(box);
}
setBox('red');
alert(box);
関数の中には関数も含まれています。この関数だけが内部の階層の関数にアクセスできます。
var box = 'blue';
function setBox() {
function setColor() {
var b = 'orange';
alert(box);
alert(b);
}
setColor(); //setColor() setBox()
}
setBox();
PS:各関数が呼び出された時に、自分の実行環境を作成します。この関数を実行すると、環境スタックに関数の環境がプッシュされて実行され、実行後は環境スタックにおいてポップアップ(終了)され、制御権は前のレベルの実行環境に渡される。PS:コードが一つの環境で実行されると、作用ドメインチェーンというものが形成されます。その用途は、実行環境におけるアクセス権限のある変数と関数の秩序的なアクセスを保証することです。作用するドメインチェーンの先端は、環境を実行する変数のオブジェクトです。
6.ブロックレベルのスコープがない
ブロックレベルのスコープは、if文などの括弧が閉じられたコードブロックを表しているので、変数を定義するために条件判定をサポートします。
if (true) { //if
var box = 'Lee';
}
alert(box);
for循環語句も同じです。
for (var i = 0; i < 10; i ++) { //
var box = 'Lee';
}
alert(i);
alert(box);
varキーワードの関数の違い
function box(num1, num2) {
var sum = num1 + num2; // var
return sum;
}
alert(box(10,10));
alert(sum); //
PS:varを使用しないで変数を初期化することを提案しません。このような方法は様々なアクシデントを引き起こすからです。したがって、変数を初期化するときは必ずvarを追加します。一般的に、変数は検索によって、その識別子が実際に何を表すかを決定する。
var box = 'blue';
function getBox() {
return box; // box
} // var box = 'red'
alert(getBox()); // red
PS:変数クエリでは、ローカル変数にアクセスすることは、グローバル変数よりも速くなります。二.メモリ問題
JavaScriptは自動ごみ収集機構を持っています。つまり、実行環境はコードの実行中に使用されるメモリを管理します。その他の言語はCとC++、手でメモリの使用状況を追跡しなければなりません。タイムリーなリリースは多くの問題を引き起こします。JavaScriptはこのようにする必要がなくて、それは自分でメモリの分配と不要なメモリの回収を管理することができます。
JavaScriptで最もよく使われているごみの収集方法はマーククリアです。ゴミ収集器は、実行時にメモリに格納されている変数にマークを付けます。次に、環境で使用されている変数のマークを削除します。マークが削除されていない変数は、削除を準備している変数と見なされます。最後に、ごみ収集器はメモリの整理作業を完了し、マーク付きの値を廃棄し、彼らが使っているメモリ空間を回収します。
ゴミ収集器は周期的に運行しています。このようにプログラム全体の性能問題が発生します。例えば、IE 7の以前のバージョンでは、そのごみ収集器はメモリ割り当て量によって運行されています。例えば、256個の変数がゴミ収集器を実行し始めます。このように、頻繁に運行しなければならないので、性能が低下します。
一般的に、最小のメモリを占有することで、ページがより良い性能を得ることができることを保証する。メモリを最適化する最善の方法は、いったんデータが役に立たなくなると、nullに設定して参照を解放することです。この方法はほとんどのグローバル変数とグローバルオブジェクトに適用されます。
var o = {
name : 'Lee'
};
o = null; // ,
もっと多くのJavaScriptに関する内容は当駅のテーマを調べられます。「JavaScript常用関数技術のまとめ」、「javascript対象向け入門教程」、「JavaScriptエラーとデバッグテクニックのまとめ」、「JavaScriptデータ構造とアルゴリズム技術のまとめ」及び「JavaScript数学演算の使い方のまとめ」本論文で述べたように、JavaScriptプログラムの設計に役に立ちます。