js ES6でのletコマンドの使い方を詳しく解説
ES6 では、変数を宣言するための let コマンドが追加されています。使い方はvarと似ていますが、宣言された変数はletコマンドが配置されているコードブロック内でのみ有効です
let
コマンド
基本的な使い方
ES6には変数を宣言するために使用される新しいletコマンドがあります。使い方は var と似ていますが、宣言された変数は let コマンドが配置されているコード ブロック内でのみ有効です。
{ let a = 10; var b = 1; } a // ReferenceError: a is not defined. b // 1
上記のコードはコード ブロック内にあり、let と var をそれぞれ使用して 2 つの変数を宣言します。次に、これら 2 つの変数はコード ブロックの外で呼び出されます。その結果、let で宣言された変数はエラーを報告し、var で宣言された変数は正しい値を返します。これは、let で宣言された変数が、それが配置されているコード ブロック内でのみ有効であることを示しています。
ループカウンターの場合、letコマンドの使用が非常に適しています。
for (let i = 0; i < 10; i++) {} console.log(i); //ReferenceError: i is not defined
上記のコードでは、カウンター i は for ループの本体内でのみ有効であり、ループの外で参照された場合はエラーが報告されます。
次のコードで var を使用する場合、最終出力は 10 です。
var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 10
上記のコードでは、変数 i は var で宣言されており、グローバル スコープで有効です。したがって、ループするたびに、新しい i 値で古い値が上書きされ、最終出力は最後のラウンドの i の値になります。
let を使用する場合、宣言された変数はブロックレベルのスコープ内でのみ有効であり、最終出力は 6 です。
var a = []; for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 6
上記のコードでは、変数 i は let によって宣言されており、現在の i はこのサイクルでのみ有効であるため、各サイクルの i は実際には新しい変数であるため、最終的な出力は 6 になります。
変数昇格はありません
letにはvarのような「変数昇格」現象がありません。したがって、変数は宣言後に使用する必要があります。そうしないと、エラーが報告されます。
console.log(foo); // 输出undefined console.log(bar); // 报错ReferenceError var foo = 2; let bar = 2;
上記のコードでは、変数 foo が var コマンドで宣言されており、変数の昇格が行われます。つまり、スクリプトの実行を開始すると、変数 foo はすでに存在しますが、値がないため、unknown が出力されます。変数 bar は let コマンドで宣言されており、変数の昇格は行われません。これは、変数 bar が宣言前には存在しないことを意味し、変数 bar が使用されるとエラーがスローされます。
一時的なデッドゾーン
let コマンドがブロックレベルのスコープに存在する限り、それによって宣言された変数はこの領域に「バインド」され、外部の影響を受けなくなります。
var tmp = 123; if (true) { tmp = 'abc'; // ReferenceError let tmp; }
上記のコードにはグローバル変数 tmp がありますが、let はブロックレベルのスコープでローカル変数 tmp を宣言しており、後者がブロックレベルのスコープをバインドするため、let が変数を宣言する前にエラーが発生します。 tmp に値を割り当てるときに報告されます。
ES6 では、ブロック内に let コマンドと const コマンドがある場合、このブロック内でこれらのコマンドによって宣言された変数は最初から閉じたスコープを形成することが明確に規定されています。宣言前にこれらの変数を使用すると、エラーが発生します。
つまり、コード ブロック内では、let コマンドを使用して宣言されるまで変数は使用できません。文法的には、これは「一時的なデッド ゾーン」(TDZ) と呼ばれます。
if (true) { // TDZ开始 tmp = 'abc'; // ReferenceError console.log(tmp); // ReferenceError let tmp; // TDZ结束 console.log(tmp); // undefined tmp = 123; console.log(tmp); // 123 }
上記のコードでは、let コマンドが変数 tmp を宣言する前に、変数 tmp の「デッド ゾーン」に属しています。
「一時的なデッドゾーン」は、typeof が 100% 安全な操作ではなくなったことも意味します。
typeof x; // ReferenceError let x;
上記のコードでは、変数 x は let コマンドを使用して宣言されているため、変数が使用されている限り、宣言される前は x の「デッドゾーン」に属しており、エラーが報告されます。したがって、typeof は実行時に ReferenceError をスローします。
比較のために、変数がまったく宣言されていない場合、typeof を使用してもエラーは報告されません。
typeof undeclared_variable // "undefined"
上記のコードでは、undeclared_variableは存在しない変数名であり、結果は「未定義」となります。したがって、let より前は、typeofoperator は 100% 安全であり、エラーを報告することはありませんでした。これはもはや真実ではありません。この設計は、誰もが良いプログラミング習慣を身につけられるようにするためのものです。変数は宣言後に使用する必要があります。そうしないと、エラーが報告されます。
一部の「デッドゾーン」は隠されており、見つけるのは簡単ではありません。
function bar(x = y, y = 2) { return [x, y]; } bar(); // 报错
上記のコードで、bar 関数の呼び出し時にエラーが報告される理由 (実装によってはエラーが報告されない場合もあります) は、パラメーター x のデフォルト値が別のパラメーター y と等しく、y が宣言されていないためです。この時点では、「デッドゾーン」に属します。 y のデフォルト値が x の場合、この時点で x が宣言されているため、エラーは報告されません。
function bar(x = 2, y = x) { return [x, y]; } bar(); // [2, 2]
ES6 では、主に実行時エラーを減らし、変数が宣言される前に使用されて予期せぬ動作が発生するのを防ぐために、一時的なデッドゾーンや let ステートメントや const ステートメントでは変数のプロモーションが発生しないことが規定されています。このようなエラーは ES5 では非常に一般的ですが、この規定により、そのようなエラーを簡単に回避できるようになりました。
つまり、一時的なデッドゾーンの本質は、現在のスコープに入るとすぐに、使用したい変数がすでに存在しますが、その変数を取得して使用できるのは の行までだけであるということです。変数を宣言するコードが表示されます。
重複した宣言は許可されません
let は、同じスコープ内の同じ変数の重複した宣言を許可しません。
// 报错 function () { let a = 10; var a = 1; } // 报错 function () { let a = 10; let a = 1; }
したがって、関数内でパラメータを再宣言することはできません。
function func(arg) { let arg; // 报错 } function func(arg) { { let arg; // 不报错 } }
ブロックレベルのスコープ
なぜブロックレベルのスコープが必要なのでしょうか?
ES5 にはグローバル スコープと 関数スコープ のみがあり、ブロックレベルのスコープがないため、多くの不合理なシナリオが発生します。
最初のシナリオでは、内部変数が外部変数を上書きする可能性があります。
var tmp = new Date(); function f() { console.log(tmp); if (false) { var tmp = "hello world"; } } f(); // undefined
上面代码中,函数f执行后,输出结果为undefined,原因在于变量提升,导致内层的tmp变量覆盖了外层的tmp变量。
第二种场景,用来计数的循环变量泄露为全局变量。
var s = 'hello'; for (var i = 0; i < s.length; i++) { console.log(s[i]); } console.log(i); // 5
上面代码中,变量i只用来控制循环,但是循环结束后,它并没有消失,泄露成了全局变量。
ES6的块级作用域
let实际上为JavaScript新增了块级作用域。
function f1() { let n = 5; if (true) { let n = 10; } console.log(n); // 5 }
上面的函数有两个代码块,都声明了变量n,运行后输出5。这表示外层代码块不受内层代码块的影响。如果使用var定义变量n,最后输出的值就是10。
ES6允许块级作用域的任意嵌套。
{{{{{let insane = 'Hello World'}}}}};
上面代码使用了一个五层的块级作用域。外层作用域无法读取内层作用域的变量。
{{{{ {let insane = 'Hello World'} console.log(insane); // 报错 }}}};
内层作用域可以定义外层作用域的同名变量。
{{{{ let insane = 'Hello World'; {let insane = 'Hello World'} }}}};
块级作用域的出现,实际上使得获得广泛应用的立即执行函数表达式(IIFE)不再必要了。
// IIFE 写法 (function () { var tmp = ...; ... }()); // 块级作用域写法 { let tmp = ...; ... }
块级作用域与函数声明
函数能不能在块级作用域之中声明,是一个相当令人混淆的问题。
ES5规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明。
// 情况一 if (true) { function f() {} } // 情况二 try { function f() {} } catch(e) { }
上面代码的两种函数声明,根据ES5的规定都是非法的。
但是,浏览器没有遵守这个规定,为了兼容以前的旧代码,还是支持在块级作用域之中声明函数,因此上面两种情况实际都能运行,不会报错。不过,“严格模式”下还是会报错。
// ES5严格模式 'use strict'; if (true) { function f() {} } // 报错
ES6 引入了块级作用域,明确允许在块级作用域之中声明函数。
// ES6严格模式 'use strict'; if (true) { function f() {} } // 不报错
ES6 规定,块级作用域之中,函数声明语句的行为类似于let,在块级作用域之外不可引用。
function f() { console.log('I am outside!'); } (function () { if (false) { // 重复声明一次函数f function f() { console.log('I am inside!'); } } f(); }());
上面代码在 ES5 中运行,会得到“I am inside!”,因为在if内声明的函数f会被提升到函数头部,实际运行的代码如下。
// ES5版本 function f() { console.log('I am outside!'); } (function () { function f() { console.log('I am inside!'); } if (false) { } f(); }());
ES6 的运行结果就完全不一样了,会得到“I am outside!”。因为块级作用域内声明的函数类似于let,对作用域之外没有影响,实际运行的代码如下。
// ES6版本 function f() { console.log('I am outside!'); } (function () { f(); }());
很显然,这种行为差异会对老代码产生很大影响。为了减轻因此产生的不兼容问题,ES6在附录B里面规定,浏览器的实现可以不遵守上面的规定,有自己的行为方式。
允许在块级作用域内声明函数。
函数声明类似于var,即会提升到全局作用域或函数作用域的头部。
同时,函数声明还会提升到所在的块级作用域的头部。
注意,上面三条规则只对ES6的浏览器实现有效,其他环境的实现不用遵守,还是将块级作用域的函数声明当作let处理。
前面那段代码,在 Chrome 环境下运行会报错。
// ES6的浏览器环境 function f() { console.log('I am outside!'); } (function () { if (false) { // 重复声明一次函数f function f() { console.log('I am inside!'); } } f(); }()); // Uncaught TypeError: f is not a function
上面的代码报错,是因为实际运行的是下面的代码。
// ES6的浏览器环境 function f() { console.log('I am outside!'); } (function () { var f = undefined; if (false) { function f() { console.log('I am inside!'); } } f(); }()); // Uncaught TypeError: f is not a function
考虑到环境导致的行为差异太大,应该避免在块级作用域内声明函数。如果确实需要,也应该写成函数表达式,而不是函数声明语句。
// 函数声明语句 { let a = 'secret'; function f() { return a; } } // 函数表达式 { let a = 'secret'; let f = function () { return a; }; }
另外,还有一个需要注意的地方。ES6的块级作用域允许声明函数的规则,只在使用大括号的情况下成立,如果没有使用大括号,就会报错。
// 不报错 'use strict'; if (true) { function f() {} } // 报错 'use strict'; if (true) function f() {}
do 表达式
本质上,块级作用域是一个语句,将多个操作封装在一起,没有返回值。
{ let t = f(); t = t * t + 1; }
上面代码中,块级作用域将两个语句封装在一起。但是,在块级作用域以外,没有办法得到t的值,因为块级作用域不返回值,除非t是全局变量。
现在有一个提案,使得块级作用域可以变为表达式,也就是说可以返回值,办法就是在块级作用域之前加上do,使它变为do表达式。
let x = do { let t = f(); t * t + 1; };
上面代码中,变量x会得到整个块级作用域的返回值。
JavaScript ES6 的 let 和 var 的比较
在javascript 1.7中, let 关键词被添加进来, 我听说它声明之后类似于”本地变量“, 但是我仍然不确定它和 关键词 var 的具体区别。
回答:
不同点在于作用域, var关键词的作用域是最近的函数作用域(如果在函数体的外部就是全局作用域), let 关键词的作用域是最接近的块作用域(如果在任何块意外就是全局作用域),这将会比函数作用域更小。
同样, 像var 一样, 使用let 声明的变量也会在其被声明的地方之前可见。
下面是Demo 例子。
全局(Global)
当在函数体之外它们是平等的。
let me = 'go'; //globally scoped var i = 'able'; //globally scoped
函数(Function)
当瞎下面这种, 也是平等的。
function ingWithinEstablishedParameters() { let terOfRecommendation = 'awesome worker!'; //function block scoped var sityCheerleading = 'go!'; //function block scoped };
块(Block)
这是不同点, let 只是在 for 循环中, var 却是在整个函数都是可见的。
function allyIlliterate() { //tuce is *not* visible out here for( let tuce = 0; tuce < 5; tuce++ ) { //tuce is only visible in here (and in the for() parentheses) }; //tuce is *not* visible out here }; function byE40() { //nish *is* visible out here for( var nish = 0; nish < 5; nish++ ) { //nish is visible to the whole function }; //nish *is* visible out here };
以上がjs ES6でのletコマンドの使い方を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

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

人気の記事

ホットツール

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

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

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

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

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

ホットトピック











CrystalDiskMark は、シーケンシャルおよびランダムの読み取り/書き込み速度を迅速に測定する、ハード ドライブ用の小型 HDD ベンチマーク ツールです。次に、編集者が CrystalDiskMark と Crystaldiskmark の使用方法を紹介します。 1. CrystalDiskMark の概要 CrystalDiskMark は、機械式ハード ドライブとソリッド ステート ドライブ (SSD) の読み取りおよび書き込み速度とパフォーマンスを評価するために広く使用されているディスク パフォーマンス テスト ツールです。 ). ランダム I/O パフォーマンス。これは無料の Windows アプリケーションで、使いやすいインターフェイスとハード ドライブのパフォーマンスのさまざまな側面を評価するためのさまざまなテスト モードを提供し、ハードウェアのレビューで広く使用されています。

foobar2000 は、音楽リソースをいつでも聴くことができるソフトウェアです。あらゆる種類の音楽をロスレス音質で提供します。音楽プレーヤーの強化版により、より包括的で快適な音楽体験を得ることができます。その設計コンセプトは、高度なオーディオをコンピュータ上で再生可能 デバイスを携帯電話に移植し、より便利で効率的な音楽再生体験を提供 シンプルでわかりやすく、使いやすいインターフェースデザイン 過度な装飾や煩雑な操作を排除したミニマルなデザインスタイルを採用また、さまざまなスキンとテーマをサポートし、自分の好みに合わせて設定をカスタマイズし、複数のオーディオ形式の再生をサポートする専用の音楽プレーヤーを作成します。過度の音量による聴覚障害を避けるために、自分の聴覚の状態に合わせて調整してください。次は私がお手伝いさせてください

NetEase Mailbox は、中国のネットユーザーに広く使用されている電子メール アドレスとして、その安定した効率的なサービスで常にユーザーの信頼を獲得してきました。 NetEase Mailbox Master は、携帯電話ユーザー向けに特別に作成された電子メール ソフトウェアで、電子メールの送受信プロセスが大幅に簡素化され、電子メールの処理がより便利になります。 NetEase Mailbox Master の使い方と具体的な機能について、以下ではこのサイトの編集者が詳しく紹介しますので、お役に立てれば幸いです。まず、モバイル アプリ ストアで NetEase Mailbox Master アプリを検索してダウンロードします。 App Store または Baidu Mobile Assistant で「NetEase Mailbox Master」を検索し、画面の指示に従ってインストールします。ダウンロードとインストールが完了したら、NetEase の電子メール アカウントを開いてログインします。ログイン インターフェイスは次のとおりです。

クラウド ストレージは今日、私たちの日常生活や仕事に欠かせない部分になっています。中国有数のクラウド ストレージ サービスの 1 つである Baidu Netdisk は、強力なストレージ機能、効率的な伝送速度、便利な操作体験により多くのユーザーの支持を得ています。また、重要なファイルのバックアップ、情報の共有、オンラインでのビデオの視聴、または音楽の聴きたい場合でも、Baidu Cloud Disk はニーズを満たすことができます。しかし、Baidu Netdisk アプリの具体的な使用方法を理解していないユーザーも多いため、このチュートリアルでは Baidu Netdisk アプリの使用方法を詳しく紹介します。まだ混乱しているユーザーは、この記事に従って詳細を学ぶことができます。 Baidu Cloud Network Disk の使用方法: 1. インストール まず、Baidu Cloud ソフトウェアをダウンロードしてインストールするときに、カスタム インストール オプションを選択してください。

MetaMask (中国語ではリトル フォックス ウォレットとも呼ばれます) は、無料で評判の高い暗号化ウォレット ソフトウェアです。現在、BTCC は MetaMask ウォレットへのバインドをサポートしており、バインド後は MetaMask ウォレットを使用してすぐにログイン、値の保存、コインの購入などが可能になり、初回バインドで 20 USDT のトライアル ボーナスも獲得できます。 BTCCMetaMask ウォレットのチュートリアルでは、MetaMask の登録方法と使用方法、および BTCC で Little Fox ウォレットをバインドして使用する方法を詳しく紹介します。メタマスクウォレットとは何ですか? 3,000 万人を超えるユーザーを抱える MetaMask Little Fox ウォレットは、現在最も人気のある暗号通貨ウォレットの 1 つです。無料で使用でき、拡張機能としてネットワーク上にインストールできます。

Windows オペレーティング システムは世界で最も人気のあるオペレーティング システムの 1 つであり、その新バージョン Win11 が大きな注目を集めています。 Win11 システムでは、管理者権限の取得は重要な操作であり、管理者権限を取得すると、ユーザーはシステム上でより多くの操作や設定を実行できるようになります。この記事では、Win11システムで管理者権限を取得する方法と、権限を効果的に管理する方法を詳しく紹介します。 Win11 システムでは、管理者権限はローカル管理者とドメイン管理者の 2 種類に分かれています。ローカル管理者はローカル コンピュータに対する完全な管理権限を持っています

OracleSQL の除算演算の詳細な説明 OracleSQL では、除算演算は一般的かつ重要な数学演算であり、2 つの数値を除算した結果を計算するために使用されます。除算はデータベース問合せでよく使用されるため、OracleSQL での除算演算とその使用法を理解することは、データベース開発者にとって重要なスキルの 1 つです。この記事では、OracleSQL の除算演算に関する関連知識を詳細に説明し、読者の参考となる具体的なコード例を示します。 1. OracleSQL での除算演算

Appleは火曜日にiOS 17.4アップデートを公開し、iPhoneに多数の新機能と修正をもたらした。このアップデートには新しい絵文字が含まれており、EU ユーザーは他のアプリ ストアから絵文字をダウンロードすることもできます。さらに、このアップデートでは iPhone のセキュリティ制御も強化され、より多くの「盗難デバイス保護」設定オプションが導入され、ユーザーにより多くの選択肢と保護が提供されます。 「iOS17.3では、「盗難デバイス保護」機能が初めて導入され、ユーザーの機密情報のセキュリティが強化されています。ユーザーが自宅やその他の身近な場所から離れている場合、この機能ではユーザーは最初に生体認証情報を入力する必要がありますApple ID パスワードの変更や盗難デバイス保護の無効化など、特定のデータにアクセスして変更するには、情報を再度入力する必要があります。
