この記事は、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
*/
var は繰り返し宣言でき、値は上書きされるため、別の
の場合、ループ変数は破棄され、for ループが直接飛び出します。 <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>
関数スコープで 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 サイトの他の関連記事を参照してください。

JavaScriptエンジンが内部的にどのように機能するかを理解することは、開発者にとってより効率的なコードの作成とパフォーマンスのボトルネックと最適化戦略の理解に役立つためです。 1)エンジンのワークフローには、3つの段階が含まれます。解析、コンパイル、実行。 2)実行プロセス中、エンジンはインラインキャッシュや非表示クラスなどの動的最適化を実行します。 3)ベストプラクティスには、グローバル変数の避け、ループの最適化、constとletsの使用、閉鎖の過度の使用の回避が含まれます。

Pythonは、スムーズな学習曲線と簡潔な構文を備えた初心者により適しています。 JavaScriptは、急な学習曲線と柔軟な構文を備えたフロントエンド開発に適しています。 1。Python構文は直感的で、データサイエンスやバックエンド開発に適しています。 2。JavaScriptは柔軟で、フロントエンドおよびサーバー側のプログラミングで広く使用されています。

PythonとJavaScriptには、コミュニティ、ライブラリ、リソースの観点から、独自の利点と短所があります。 1)Pythonコミュニティはフレンドリーで初心者に適していますが、フロントエンドの開発リソースはJavaScriptほど豊富ではありません。 2)Pythonはデータサイエンスおよび機械学習ライブラリで強力ですが、JavaScriptはフロントエンド開発ライブラリとフレームワークで優れています。 3)どちらも豊富な学習リソースを持っていますが、Pythonは公式文書から始めるのに適していますが、JavaScriptはMDNWebDocsにより優れています。選択は、プロジェクトのニーズと個人的な関心に基づいている必要があります。

C/CからJavaScriptへのシフトには、動的なタイピング、ゴミ収集、非同期プログラミングへの適応が必要です。 1)C/Cは、手動メモリ管理を必要とする静的に型付けられた言語であり、JavaScriptは動的に型付けされ、ごみ収集が自動的に処理されます。 2)C/Cはマシンコードにコンパイルする必要がありますが、JavaScriptは解釈言語です。 3)JavaScriptは、閉鎖、プロトタイプチェーン、約束などの概念を導入します。これにより、柔軟性と非同期プログラミング機能が向上します。

さまざまなJavaScriptエンジンは、各エンジンの実装原則と最適化戦略が異なるため、JavaScriptコードを解析および実行するときに異なる効果をもたらします。 1。語彙分析:ソースコードを語彙ユニットに変換します。 2。文法分析:抽象的な構文ツリーを生成します。 3。最適化とコンパイル:JITコンパイラを介してマシンコードを生成します。 4。実行:マシンコードを実行します。 V8エンジンはインスタントコンピレーションと非表示クラスを通じて最適化され、Spidermonkeyはタイプ推論システムを使用して、同じコードで異なるパフォーマンスパフォーマンスをもたらします。

現実世界におけるJavaScriptのアプリケーションには、サーバー側のプログラミング、モバイルアプリケーション開発、モノのインターネット制御が含まれます。 2。モバイルアプリケーションの開発は、ReactNativeを通じて実行され、クロスプラットフォームの展開をサポートします。 3.ハードウェアの相互作用に適したJohnny-Fiveライブラリを介したIoTデバイス制御に使用されます。

私はあなたの日常的な技術ツールを使用して機能的なマルチテナントSaaSアプリケーション(EDTECHアプリ)を作成しましたが、あなたは同じことをすることができます。 まず、マルチテナントSaaSアプリケーションとは何ですか? マルチテナントSaaSアプリケーションを使用すると、Singの複数の顧客にサービスを提供できます

この記事では、許可によって保護されたバックエンドとのフロントエンド統合を示し、next.jsを使用して機能的なedtech SaaSアプリケーションを構築します。 FrontEndはユーザーのアクセス許可を取得してUIの可視性を制御し、APIリクエストがロールベースに付着することを保証します


ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

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

人気の記事

ホットツール

AtomエディタMac版ダウンロード
最も人気のあるオープンソースエディター

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

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

WebStorm Mac版
便利なJavaScript開発ツール

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