ホームページ >ウェブフロントエンド >jsチュートリアル >JS スコープに関する 5 つの落とし穴 (概要)

JavaScript では、ブロック、関数、またはモジュールによって変数のスコープが作成されます。たとえば、if コード ブロックは、変数 message のスコープを作成します。
if (true) {
const message = 'Hello';
console.log(message); // 'Hello'
}
console.log(message); // throws ReferenceErrormessage## は、## のスコープ内でアクセスできます。 #if コード ブロック #。ただし、スコープ外では変数にアクセスできません。 さて、これでスコープについて簡単に説明しました。さらに詳しく知りたい場合は、私の記事
を読むことをお勧めします。 ここでは、JavaScript スコープが予想とは異なる動作をする 5 つの興味深い状況を紹介します。範囲についての理解を深めたり、単に面接の準備をするために、これらのケースを研究することもできます。
1.const colors = ['red', 'blue', 'white'];
for (let i = 0, var l = colors.length; i < l; i++) {
console.log(colors[i]); // 'red', 'blue', 'white'
}
console.log(l); // ???
console.log(i); // ???l
変数と i 変数を出力するとどうなりますか?
3 を出力しますが、console.log(i ) は ReferenceError をスローします。 l
var ステートメントを使用して宣言されます。すでにご存じのとおり、var 変数 は、コード ブロックではなく、関数本体 のスコープによってのみ制限されます。 対照的に、変数 i
let ステートメントを使用して宣言されます。 let 変数はブロック スコープであるため、i は for ループ スコープ内でのみアクセスできます。 修正
var l = Colors.length から const l = Colors に変更します。長さ###。これで、変数 l が for ループ本体にカプセル化されました。 2. コード ブロックでの関数宣言
// ES2015 env
{
function hello() {
return 'Hello!';
}
}
hello(); // ???Call は次のようになります。 ?
(コード スニペットは ES2015 環境で実行されます)回答
が発生します。 興味深いことに、ES2015 より前の環境では、上記のコード スニペットを実行してもエラーはスローされません。 ###なぜなのかご存知ですか?以下のコメント欄に答えを書いてください。
3. モジュールはどこでインポートできますか?
コード ブロックでモジュールをインポートできますか?if (true) {
import { myFunc } from 'myModule'; // ???
myFunc();
}回答モジュール スコープ とも呼ばれます) にのみインポートできます。
import { myFunc } from 'myModule';
if (true) {
myFunc();
}import ステートメントは実行時に実行されるため、コード ブロックまたは関数に含めることはできません。
4. 関数パラメータのスコープ
let p = 1;
function myFunc(p = p + 1) {
return p;
}
myFunc(); // ???myFunc()回答
これは、関数のパラメーターに独自のスコープ (関数スコープとは別) があるために発生します。引数 p = p 1 は let p = p 1
p = p 1 を詳しく見てみましょう。
p を定義します。次に、JavaScript はデフォルト値式 p 1
p は作成されていますが、まだ初期化されていません (外部スコープ let から変数にアクセスできません) p = 1)。したがって、初期化前に p がアクセスされたというエラーがスローされます。 修正
関数パラメーターの名前を変更することを選択しましょう:
let p = 1;
function myFunc(q = p + 1) {
return q;
}
myFunc(); // => 2関数パラメーターの名前が p から q
に変更されます。myFunc() が呼び出されるとき、パラメータは指定されていないため、パラメータ q はデフォルト値 p 1 に初期化されます。 p 1 を評価するには、外部スコープの変数 p にアクセスします: p 1 = 1 1 = 2。
以下代码在代码块内定义了一个函数和一个类:
if (true) {
function greet() {
// function body
}
class Greeter {
// class body
}
}
greet(); // ???
new Greeter(); // ???是否可以在块作用域之外访问 greet 和 Greeter? (考虑 ES2015 环境)
function 和 class 声明都是块作用域的。所以在代码块作用域外调用函数 greet() 和构造函数 new Greeter() 就会抛出 ReferenceError。
必须注意 var 变量,因为它们是函数作用域的,即使是在代码块中定义的。
由于 ES2015 模块系统是静态的,因此你必须在模块作用域内使用 import 语法(以及 export)。
函数参数具有其作用域。设置默认参数值时,请确保默认表达式内的变量已经用值初始化。
在 ES2015 运行时环境中,函数和类声明是块作用域的。但是在 ES2015 之前的环境中,函数声明仅在函数作用域内。
希望这些陷阱能够帮你巩固作用域知识!
英文原文地址:https://dmitripavlutin.com/javascript-scope-gotchas/
作者:Dmitri Pavlutin
更多编程相关知识,请访问:编程入门!!
以上がJS スコープに関する 5 つの落とし穴 (概要)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。