検索
ホームページウェブフロントエンドjsチュートリアルJSスコープとスコープチェーンを詳しく解説_基礎知識

(1) 範囲

変数のスコープとは、プログラムのソースコード内で定義された変数の領域です。

1. JS で字句スコープが使用されます

関数内で宣言されていない変数 (関数内で var が省略されている場合もグローバルとみなされます) は、グローバル変数 (グローバル スコープ) と呼ばれます

関数内で宣言された変数は関数スコープを持ち、ローカル変数です

ローカル変数はグローバル変数よりも優先されます

コードをコピーします コードは次のとおりです:

var name="one";
関数テスト(){
var name="two";
console.log(name); //2
}
テスト();

関数内で var を省略すると、実際にはグローバル変数に書き換えられるため、グローバル変数に影響します

コードをコピーします コードは次のとおりです:

var name="one";
関数テスト(){
name="2";
}
テスト();
console.log(name); //2

関数スコープ、つまり関数はスコープの基本単位です。js には if for などの c/c のようなブロックレベルのスコープがありません。

コードをコピーします コードは次のとおりです:

関数テスト(){
for(var i=0;i If(i==5){
var name = "one";
}
}
console.log(名前); // 1 つ
}
test(); //関数レベルのスコープなので、name="one"
にアクセスできます。

もちろん、js では高階関数も使用されており、実際には入れ子関数として理解できます

コードをコピーします コードは次のとおりです:

関数 test1(){
var name = "one";
戻り関数 (){
console.log(名前);
}
}
test1()();

test1()の後、外側の関数が呼び出され、内側の関数が返され、Continue()すると、それに応じて内側の関数が呼び出されて実行されるため、「one」

が出力されます。

ネストされた関数にはクロージャが含まれます。これについては後で説明します。ここで、内側の関数は外側の関数で宣言された変数名にアクセスできます。これにはスコープ チェーン メカニズムが関係します。

2. 事前にJSで宣言

js の関数スコープは、関数内で宣言されたすべての変数が関数本体内で常に表示されることを意味します。また、宣言前に変数を使用することもできます。この状況をホイスティング

と呼びます。

ヒント: 事前宣言は、JS エンジンのプリコンパイル時に行われます。事前宣言は、コードが実行される前に発生します。

たとえば

コードをコピーします コードは次のとおりです:

var name="one";
関数テスト(){
console.log(name); //未定義
var name="two";
console.log(name); //2
}
テスト();

上記により次のような効果が得られます

コードをコピーします コードは次のとおりです:

var name="one";
関数テスト(){
変数名;
console.log(name); //未定義
name="2";
console.log(name); //2
}
テスト();

var をもう一度削除してみますか?これはグローバル変数になった関数内の名前なので、未定義ではなくなりました

コードをコピーします コードは次のとおりです:

var name="one";
関数テスト(){
console.log(名前); // 1 つ
name="2";
console.log(name); //2
}
テスト();

3. テストにパラメータがある場合は、上記のパラメータが渡されないことに注意してください。

コードをコピー コードは次のとおりです:

関数テスト(名前){
console.log(名前); // 1 つ
name="2";
console.log(name); //2
}
var name = "one";
テスト(名前);
console.log(name); // 1 つ

前に述べたように、基本型は値によって渡されるため、テストに渡される名前は実際には単なるコピーであり、関数が返された後にこのコピーはクリアされます。
関数内の name="two" がグローバル名を変更するとは考えないでください。これらは 2 つの独立した名前であるためです

(2) スコープチェーン

上記の高度な機能にはスコープ チェーンが含まれます

コードをコピーします コードは次のとおりです:

関数 test1(){
var name = "one";
戻り関数 (){
console.log(名前);
}
}
test1()();

1. 説明するために大きな段落を導入します:
JavaScript コードの各部分 (グローバル コードまたは関数) には、スコープ チェーンが関連付けられています。

このスコープ チェーンは、オブジェクトのリストまたはリンクされたリストであり、このオブジェクトのグループは、このコードの「スコープ内」の変数を定義します。

js が変数 x の値を見つける必要がある場合 (このプロセスは変数解決と呼ばれます)、このオブジェクトに x という名前の属性がある場合、この属性の値は次のようになります。最初のオブジェクトに x という名前の属性がない場合、js はチェーン内の次のオブジェクトの検索を続けます。 2 番目のオブジェクトに x という名前の属性がまだない場合は、引き続き次のオブジェクトの検索が続きます。スコープ チェーン内のオブジェクトに属性 x が含まれていない場合、x はこのコードのスコープ チェーンに存在しないとみなされ、最終的に ReferenceError 例外がスローされます。

2. スコープチェーンの例:

js のトップレベル コード (つまり、関数定義が含まれていないコード) では、スコープ チェーンはグローバル オブジェクトで構成されます。

ネストを含まない関数本体には、スコープ チェーン上に 2 つのオブジェクトがあります。1 つ目は関数パラメータとローカル変数を定義するオブジェクトで、2 つ目はグローバル オブジェクトです。

ネストされた関数本体では、スコープ内に少なくとも 3 つのオブジェクトがあります。

3. スコープチェーン作成ルール:

関数が定義されると (定義されたときに関数が開始されることに注意してください)、実際にはスコープ チェーンが保存されます。

この関数が呼び出されると、そのパラメーターまたはローカル変数を格納するための新しいオブジェクトが作成され、そのオブジェクトがそのスコープ チェーンに追加され、関数呼び出しスコープの新しいより長い表現「チェーン」が作成されます。

入れ子関数の場合は、状況が再び変わります。外部関数が呼び出されるたびに、内部関数が再定義されます。外部関数が呼び出されるたびにスコープ チェーンが異なるためです。内部関数は定義されるたびに微妙に異なる必要があります。内部関数のコードは外部関数が呼び出されるたびに同じであり、このコードに関連付けられたスコープ チェーンも異なります。

(ヒント: 上記の 3 つのポイントをよく理解して、覚えておいてください。自分の言葉で言うのが最善です。そうでないと、面接官が直接「スコープ チェーンについて説明してください。」と質問するため、覚えておく必要があります。 )

スコープチェーンの実際的な例:

コードをコピーします コードは次のとおりです:

var name="one";
関数テスト(){
var name="two";
関数 test1(){
var name="three";
console.log(名前); //3
}
関数 test2(){
console.log(name); // 2 つの
}
test1();
test2();
}
テスト();

上記はネストされた関数です。これに応じて、スコープ チェーンには 3 つのオブジェクトが存在する必要があります
次に、呼び出し時に name の値を見つける必要があります。スコープ チェーンで

を検索するだけです。

test1() が正常に呼び出された場合、順序は test1()->test()-> グローバル オブジェクト ウィンドウです。 name の値 3 が test1() で見つかったので、検索が完了し、

test1() が正常に呼び出された場合、順序は test2()->test()->global object window になります。test2() では name の値が見つからないため、test() で探します。 ) を検索し、name の値が 2 の場合、検索は完了し、

が返されます。

別の例としては、面接中に時々間違いを犯したり、騙されたりすることがよくあります。

コードをコピー コードは次のとおりです:

ttp://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
http://www.w3.org/1999/xhtml">









为什么?
根据作用域链中变量的寻找规则:

复制代码 代码如下:

b.addEventListener("click",function(){
            alert("Button" i);
        },false);

这里有一个函数,它是匿名函数,既然是函数,那就在作用域链上具有一个对象,这个函数里边使用到了变量i,它自然会在作用域上寻找它。
查找顺序是 这个匿名函数 -->外部的函数buttonInit() -->全局对象window

匿名函数中找不到i,自然跑到了buttonInit(), ok,在for中找到了,

这时注册事件已经结束了,不要以为它会一个一个把i放下来,因为函数作用域之内的变量对作用域内是一直可见的,就是说会保持到最后的状态

当匿名函数要使用i的时候,注册事件完了,i已经变成了4,所以都是Button4

那怎么解决呢?

给它传值进去吧,每次循环时,再使用一个匿名函数,把for里边的i传进去,匿名函数的规则如代码

复制代码 代码如下:

ttp://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
http://www.w3.org/1999/xhtml">









这样就可以 Button1..2..3了

4.上述就是作用域链的基本描述,另外,with语句可用于临时拓展作用域链(不推荐使用with)

语法形如:

with(object)

statement

这个with语句,将object添加到作用域链的头部,然后执行statement,最后把作用域链恢复到原始状态

简单用法:

比如给表单中各个项的值value赋值

一般可以我们直接这样

复制代码 代码如下:

var f = document.forms[0];
f.name.value = "";
f.age.value = "";
f.email.value = "";

After introducing with (because using with will cause a series of problems, so let’s use the form above)

Copy code The code is as follows:

with(document.forms[0]){
f.name.value = "";
f.age.value = "";
f.email.value = "";
}

In addition, if an object o has an x ​​attribute, o.x = 1;
Then use

Copy code The code is as follows:

with(o){
x = 2;
}

can be converted into o.x = 2;
If o does not define attribute x, its function is just equivalent to x = 2; a global variable.

Because with provides a shortcut to read the attributes of o, but it cannot create attributes that o itself does not have.

The above is the entire content of this article. I hope it will be helpful to everyone learning javascript.

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
JavaScriptはCで書かれていますか?証拠を調べるJavaScriptはCで書かれていますか?証拠を調べるApr 25, 2025 am 12:15 AM

はい、JavaScriptのエンジンコアはCで記述されています。1)C言語は、JavaScriptエンジンの開発に適した効率的なパフォーマンスと基礎となる制御を提供します。 2)V8エンジンを例にとると、そのコアはCで記述され、Cの効率とオブジェクト指向の特性を組み合わせて書かれています。3)JavaScriptエンジンの作業原理には、解析、コンパイル、実行が含まれ、C言語はこれらのプロセスで重要な役割を果たします。

JavaScriptの役割:WebをインタラクティブでダイナミックにするJavaScriptの役割:WebをインタラクティブでダイナミックにするApr 24, 2025 am 12:12 AM

JavaScriptは、Webページのインタラクティブ性とダイナミズムを向上させるため、現代のWebサイトの中心にあります。 1)ページを更新せずにコンテンツを変更できます。2)Domapiを介してWebページを操作する、3)アニメーションやドラッグアンドドロップなどの複雑なインタラクティブ効果、4)ユーザーエクスペリエンスを改善するためのパフォーマンスとベストプラクティスを最適化します。

CおよびJavaScript:接続が説明しましたCおよびJavaScript:接続が説明しましたApr 23, 2025 am 12:07 AM

CおよびJavaScriptは、WebAssemblyを介して相互運用性を実現します。 1)CコードはWebAssemblyモジュールにコンパイルされ、JavaScript環境に導入され、コンピューティングパワーが強化されます。 2)ゲーム開発では、Cは物理エンジンとグラフィックスレンダリングを処理し、JavaScriptはゲームロジックとユーザーインターフェイスを担当します。

Webサイトからアプリまで:JavaScriptの多様なアプリケーションWebサイトからアプリまで:JavaScriptの多様なアプリケーションApr 22, 2025 am 12:02 AM

JavaScriptは、Webサイト、モバイルアプリケーション、デスクトップアプリケーション、サーバー側のプログラミングで広く使用されています。 1)Webサイト開発では、JavaScriptはHTMLおよびCSSと一緒にDOMを運用して、JQueryやReactなどのフレームワークをサポートします。 2)ReactNativeおよびIonicを通じて、JavaScriptはクロスプラットフォームモバイルアプリケーションを開発するために使用されます。 3)電子フレームワークにより、JavaScriptはデスクトップアプリケーションを構築できます。 4)node.jsを使用すると、JavaScriptがサーバー側で実行され、高い並行リクエストをサポートします。

Python vs. JavaScript:ユースケースとアプリケーションと比較されますPython vs. JavaScript:ユースケースとアプリケーションと比較されますApr 21, 2025 am 12:01 AM

Pythonはデータサイエンスと自動化により適していますが、JavaScriptはフロントエンドとフルスタックの開発により適しています。 1. Pythonは、データ処理とモデリングのためにNumpyやPandasなどのライブラリを使用して、データサイエンスと機械学習でうまく機能します。 2。Pythonは、自動化とスクリプトにおいて簡潔で効率的です。 3. JavaScriptはフロントエンド開発に不可欠であり、動的なWebページと単一ページアプリケーションの構築に使用されます。 4. JavaScriptは、node.jsを通じてバックエンド開発において役割を果たし、フルスタック開発をサポートします。

JavaScript通訳者とコンパイラにおけるC/Cの役割JavaScript通訳者とコンパイラにおけるC/Cの役割Apr 20, 2025 am 12:01 AM

CとCは、主に通訳者とJITコンパイラを実装するために使用されるJavaScriptエンジンで重要な役割を果たします。 1)cは、JavaScriptソースコードを解析し、抽象的な構文ツリーを生成するために使用されます。 2)Cは、Bytecodeの生成と実行を担当します。 3)Cは、JITコンパイラを実装し、実行時にホットスポットコードを最適化およびコンパイルし、JavaScriptの実行効率を大幅に改善します。

JavaScript in Action:実際の例とプロジェクトJavaScript in Action:実際の例とプロジェクトApr 19, 2025 am 12:13 AM

現実世界でのJavaScriptのアプリケーションには、フロントエンドとバックエンドの開発が含まれます。 1)DOM操作とイベント処理を含むTODOリストアプリケーションを構築して、フロントエンドアプリケーションを表示します。 2)node.jsを介してRestfulapiを構築し、バックエンドアプリケーションをデモンストレーションします。

JavaScriptとWeb:コア機能とユースケースJavaScriptとWeb:コア機能とユースケースApr 18, 2025 am 12:19 AM

Web開発におけるJavaScriptの主な用途には、クライアントの相互作用、フォーム検証、非同期通信が含まれます。 1)DOM操作による動的なコンテンツの更新とユーザーインタラクション。 2)ユーザーエクスペリエンスを改善するためにデータを提出する前に、クライアントの検証が実行されます。 3)サーバーとのリフレッシュレス通信は、AJAXテクノロジーを通じて達成されます。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター