var を簡単に理解して、JavaScript 変数またはループを導入する
この記事は、javascript に関する関連知識を提供するもので、主に var と let in JavaScript の変数やループの詳細な説明を紹介しており、テーマを中心に詳細な内容を紹介しています。値については、以下で見てみましょう。皆様のお役に立てれば幸いです。
[関連する推奨事項: JavaScript ビデオ チュートリアル 、Web フロントエンド ]
で var を使用します。 for ループ 宣言の初期化によって引き起こされる問題
// 一道经典面试题: var funcs = []; for (var i = 0; i < 3; i++) { funcs[i] = function() { console.log("My value: " + i) }; } for (var j = 0; j < 3; j++) { funcs[j](); } /* 输出结果: > My value: 3 > My value: 3 > My value: 3 */
この現象が発生する理由は次のとおりです:
- var 宣言のスコープは、関数のスコープではなく、関数のスコープです。ブロック レベルのスコープなので、for ループの初期化時に定義された var 変数は、for ループのループ本体の外側でもアクセスできます。
- そして、ループの終了後にアクセスされた場合、アクセスされる var 変数はループの完了後の値になります。
解決策
クロージャを使用する
ES5時代の解決策は、IIFEを通じてクロージャを作成し、変数を関数本体に保存してから、 function 外側の var 変数にはアクセスしません。
var funcs = []; for (var i = 0; i < 3; i++) { // 1. 闭包 funcs[i] = (function (i) { return function () { console.log("My value: " + i); }; })(i); } for (var j = 0; j < 3; j++) { funcs[j](); }
let 変数の初期化を使用する
let ステートメントはブロック レベルのスコープであり、ループ本体内の変数がブロック ステートメントの外部に漏洩することはありません。
したがって、ループ終了後に変数 i にアクセスする場合、外側のスコープの変数からの干渉はなく、アクセスされるのは当然関数本体に保存されている変数の値になります。
var funcs = []; // 2. let for (let i = 0; i < 3; i++) { funcs[i] = function() { console.log("My value: " + i); }; } for (var j = 0; j < 3; j++) { funcs[j](); }
ここから、var を使用して for ループ自体を初期化することは直感に反していることもわかります。
for ループの初期化に使用される変数は、for ループのローカル変数である必要があります。この変数は、ループの終了後は意味を持たなくなります。
ただし、var を使用して初期化する場合、var で宣言された変数のスコープは関数スコープであるため、この初期化変数は for ループと同じスコープ内にあり、for ループの制限を受けません。
for ループのローカル変数のはずですが、for ループと同じレイヤーのスコープに公開されており、ループの回数によって変数値が変更されているため、当然影響を受けます。ループ終了後の変数への他のコードのアクセス。
let を使用して for ループを初期化する場合、この問題は発生しません。これは、let で宣言されたスコープがブロックレベルのスコープであり、この初期化変数が for ループのローカル変数になるためです。期待される。
for ループは let と var で宣言された初期化変数をどのように処理しますか?
最初に結論:
- var で初期化する場合、for ループは作成された var を直接使用して変数を初期化します。 let で初期化すると、括弧は独自のスコープを形成し、for ループは括弧内の変数値をループ本体に渡します。
、 仕様には次のように書かれています:
はい仕様では var 初期化変数に対して特別な処理が行われていないため、直接使用できることがわかります。現時点では、
コードを使用してそれを証明してみましょう:
var funcs = [];
for (var i = 0; i < 3; i++) {
// !!!重复声明了一个同名的var变量
var i = 5;
console.log("My value: " + i);
}
/*
只会输出一次:
> My value: 5
*/
の場合、ループ変数は破棄され、for ループが直接飛び出します。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>var funcs = [];
for (var i = 0; i < 3; i++) {
// 用let声明了一个和循环变量同名的变量
let i = 5;
console.log("My value: " + i);
}
/*
一共输出了3次:
> My value: 5
> My value: 5
> My value: 5
*/</pre><div class="contentsignin">ログイン後にコピー</div></div>
関数スコープで var 変数を初期化し、ループ本体の let 変数はブロック スコープにあります。ループ本体の let 変数はブロック スコープの let 変数に優先的にアクセスします。ループ本体の i 値は上書きされます。
そして、var 変数は実際には let 変数の外側のスコープ内にあるため、let 変数は繰り返し宣言されず、エラーは報告されません。var 変数も予定どおりループ変数としての使命を完了します。
2 番目の結論を見てみましょう。最初に仕様も見てみましょう:let を使用して初期化すると、var を使用するよりも呼び出し ## が 1 つ多くなるのは明らかです。 #perIterationLets
のもの。perIterationLets
仕様からわかるように、
perIterationLets
LexicalDeclaration (字句宣言) の
boundNames から来ています。
そして、この
LexicalDeclaration (字句宣言)
let ステートメントを使用して for ループを初期化すると、let 変数は var 変数のように for ループ内で直接使用されず、代わりに let 変数が最初に収集され、フォームは
perIterationLets
perIterationLets
は何に使用されますか? 仕様からわかるように、let 変数は、ループ本体である perIterationLets
ForBodyEvaluation に渡されます。
ループ本体では、
perIterationLets
CreatePerIterationEnvironment のパラメーターとして実行します。<p>从字面上理解,<code>CreatePerIterationEnvironment
意思就是每次循环都要创建的环境。
要注意,这个环境不是{...}
里的那些执行语句所处的环境。 {...}
里的执行语句是statement
,在规范里可以看到,stmt
有自己的事情要做。
这个环境是属于圆括号的作用域,也就是我们定义的let初始化变量所在的作用域。
再看看每次循环都要创建的环境被用来干嘛了:
逐步分析一下方法:CreatePerIterationEnvironment
这个
- 首先,把当前执行上下文的词法环境保存下来,作为
lastIterationEnv(上一次循环时的环境)
; - 创建一个和
lastIterationEnv
同级的新作用域,作为thisIterationEnv(本次循环的环境)
; - 遍历我们定义的let初始化变量,也就是
perIterationLets
,在thisIterationEnv(本次循环的环境)
里创建一个同名的可变绑定,找到它们在lastIterationEnv(上一次循环时的环境)
里的终值,作为这个同名绑定的初始值; - 最后,将
thisIterationEnv(本次循环的环境)
交还给执行上下文。
简而言之就是,for循环会在迭代之前创建一个和初始化变量同名的变量,并使用之前迭代的终值将这个变量初始化以后,再交还给执行上下文。
用伪代码理解一下这个过程就是:
到这里又有一个问题,既然把圆括号内的变量向循环体里传递了,那如果在循环体里又重复声明了一个同名变量,算不算重复声明,会不会报错?
答案是不会。
因为CreatePerIterationEnvironment
在执行时,在新环境里创建的是一个可变的绑定,因此如果在循环体内重复声明一个名字为i
的变量,只是会影响循环体内执行语句对i
值的访问。
var funcs = []; for (let i = 0; i < 3; i++) { // !!!用let声明了一个和循环变量同名的变量 let i = 5; console.log("My value: " + i); } /* 一共输出了3次: > My value: 5 > My value: 5 > My value: 5 */
总结
在for循环中使用var声明来初始化的话,循环变量会暴露在和for循环同一作用域下,导致循环结束后还能访问到循环变量,且访问到的变量值是经过循环迭代后的值。
解决这个问题的方法如下:
- 使用闭包将循环变量的值作为局部变量保存起来;
- 使用ES6的let声明,将循环变量的作用域限制在for循环内部,初始化变量始终是for循环的局部变量,不能在外界被访问到。
for循环是怎么处理用let和var声明的初始化变量的?
- 用var初始化时,for循环会直接使用创建的var初始化变量;
- 用let初始化时,圆括号会自成一个作用域,for循环会将圆括号内的变量值往循环体内传递。
【相关推荐:javascript视频教程、web前端】
以上がvar を簡単に理解して、JavaScript 変数またはループを導入するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 はじめに: 技術の継続的な発展により、音声認識技術は人工知能の分野の重要な部分になりました。 WebSocket と JavaScript をベースとしたオンライン音声認識システムは、低遅延、リアルタイム、クロスプラットフォームという特徴があり、広く使用されるソリューションとなっています。この記事では、WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法を紹介します。

WebSocketとJavaScript:リアルタイム監視システムを実現するためのキーテクノロジー はじめに: インターネット技術の急速な発展に伴い、リアルタイム監視システムは様々な分野で広く利用されています。リアルタイム監視を実現するための重要なテクノロジーの 1 つは、WebSocket と JavaScript の組み合わせです。この記事では、リアルタイム監視システムにおける WebSocket と JavaScript のアプリケーションを紹介し、コード例を示し、その実装原理を詳しく説明します。 1.WebSocketテクノロジー

JavaScript と WebSocket を使用してリアルタイム オンライン注文システムを実装する方法の紹介: インターネットの普及とテクノロジーの進歩に伴い、ますます多くのレストランがオンライン注文サービスを提供し始めています。リアルタイムのオンライン注文システムを実装するには、JavaScript と WebSocket テクノロジを使用できます。 WebSocket は、TCP プロトコルをベースとした全二重通信プロトコルで、クライアントとサーバー間のリアルタイム双方向通信を実現します。リアルタイムオンラインオーダーシステムにおいて、ユーザーが料理を選択して注文するとき

WebSocket と JavaScript を使用してオンライン予約システムを実装する方法 今日のデジタル時代では、ますます多くの企業やサービスがオンライン予約機能を提供する必要があります。効率的かつリアルタイムのオンライン予約システムを実装することが重要です。この記事では、WebSocket と JavaScript を使用してオンライン予約システムを実装する方法と、具体的なコード例を紹介します。 1. WebSocket とは何ですか? WebSocket は、単一の TCP 接続における全二重方式です。

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 はじめに: 今日、天気予報の精度は日常生活と意思決定にとって非常に重要です。テクノロジーの発展に伴い、リアルタイムで気象データを取得することで、より正確で信頼性の高い天気予報を提供できるようになりました。この記事では、JavaScript と WebSocket テクノロジを使用して効率的なリアルタイム天気予報システムを構築する方法を学びます。この記事では、具体的なコード例を通じて実装プロセスを説明します。私たちは

使用法: JavaScript では、insertBefore() メソッドを使用して、DOM ツリーに新しいノードを挿入します。このメソッドには、挿入される新しいノードと参照ノード (つまり、新しいノードが挿入されるノード) の 2 つのパラメータが必要です。

JavaScript チュートリアル: HTTP ステータス コードを取得する方法、特定のコード例が必要です 序文: Web 開発では、サーバーとのデータ対話が頻繁に発生します。サーバーと通信するとき、多くの場合、返された HTTP ステータス コードを取得して操作が成功したかどうかを判断し、さまざまなステータス コードに基づいて対応する処理を実行する必要があります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法を説明し、いくつかの実用的なコード例を示します。 XMLHttpRequestの使用

JavaScript は Web 開発で広く使用されているプログラミング言語であり、WebSocket はリアルタイム通信に使用されるネットワーク プロトコルです。 2 つの強力な機能を組み合わせることで、効率的なリアルタイム画像処理システムを構築できます。この記事では、JavaScript と WebSocket を使用してこのシステムを実装する方法と、具体的なコード例を紹介します。まず、リアルタイム画像処理システムの要件と目標を明確にする必要があります。リアルタイムの画像データを収集できるカメラ デバイスがあるとします。
