三菱m80システムはパスワード解読の鍵を開けます

Mitsubishi m80システムロック解除パスワード変数の昇格は、変数スコープによって決定されます。つまり、グローバルスコープで宣言された変数はグローバルの最上位に昇格され、関数で宣言された変数は関数スコープの最上位にのみ昇格されます。
エントリレベルの
ジレンマ:
console.log(a);
var a = 0;
コードをコピーすると、これは報告されません:Uncaught ReferenceError:a is not defined。
代わりに、未定義を出力します。
変数の昇格後の結果は次のとおりです:
var a;
console.log(a);
a = 0;
コードをクラスにコピー
例1:
var x = 0;
function a(){
console.log(x);
let x = 1 ;
}
a();
コードをコピーするlet xが変数を昇格しない場合、xは実際には0を出力するはずです:
VM296:3 Uncaught ReferenceError:初期化の前
にa(:3:14)
'x'にアクセスできません: 1:1
エラーではありませんx定義されていませんが、アクセスできません。
このエラーの理由は何ですか?
例2:
a = aとします。
let a = a;
コードをコピーすると、どのエラーが報告されると思いますか?
「定義されていません」または「初期化前に 'a'にアクセスできません」?
実際にはそうではありませんが、エラー:aはすでに宣言されています。

ここでは次のようになります。letは「変数の昇格」も行います。昇格されない場合、例1のxは0を出力し、例2は未定義のエラーを報告します。
しかし、変数が昇格される場合、それは正当化されません。上記の例1はundefinedを出力するはずです。
したがって、これを「一時的なデッドゾーン」と呼びます。
実際、これは変数プロモーションでも、私たちが理解している変数プロモーションでもありません。一時的なデッドゾーンとは何ですか?
Letは、「特別な宣言」プロセスで変数を定義します。JSが事前解析するとき、定義されたletおよびconstの「特別な宣言」を、「レイズハンド」と同様に事前に進めます。JSエンジンは、同じスコープと同じ変数を指定します「レイズ」は1回のみ可能です。
これは、varの定義と割り当てとは異なります。varの宣言は、varがすでに宣言されている場合、後者は直接その宣言を無視するというものです。
このトピックに戻ります。
let a = a; //変数aを定義し、一時的にa1として識別します
let a = a; //変数aを定義し、一時的にa2として識別し
ますコードをコピーして事前解析し、a1を宣言してから、今度はa2を宣言する準備をします、 JSエンジンは、a2が宣言されたときにa1がすでに宣言されていることを検出しました。
したがって、「同じスコープ、同じ変数は一度しか宣言できない」という規則に違反し、エラーが直接報告されます。実際、コードで割り当てられた変数はまだ読み込まれていません(変数が読み込まれると、変数未定義エラーがスローされる場合があります)。
したがって、エラーが報告されます。エラーの内容:a2が宣言されています(aはa1によって宣言されています)。
したがって、上記の例1に戻ると、コードがxを読み取ると、letによって宣言されたxがあることがわかりますが、初期化されておらず、xにアクセスできないというエラーが直接報告されます。
ではlet変数の「特別な宣言」の魔法とは何でしょうか。
実際、let変数が昇格されたときに導入されたdeclareDataを導入するのはJSエンジンであり、事前解決中に、すべてのletおよびconst宣言データをスコープに格納します。
実際、スコープ内のすべての関数と変数を作成するには、それらがdeclareDataの値と競合するかどうかを確認する必要があります。
例3:
var a = 1; //変数aを定義し、一時的にa1とラベルを付けた
let a = 2; //変数aを定義し、一時的にa2をラベルを付け、
コードdeclareDataをコピーして変数a2を宣言し、変数a1を定義する準備をして、declareDataを見つけるA2は既に宣言されており、エラーが直接報告されます。変数aがa2によって宣言されているため、a1が宣言されています。
関数の昇格
関数の昇格は変数の昇格に似ていますが、少し異なります。
関数式
console.log(a); //未定義の変数
a = function(){}

console.log(a); //関数a
関数a(){}
コピーコード関数式は昇格を宣言しません。変数var aの変数昇格のため、最初の出力例は未定義ではなく未定義です。 。
ブロックレベルのスコープ
console.log(a); // undefined
if(true){
console.log(a); // function a
function a(){}
}
コードがコピーされて昇格された場合、ブロックレベルの効果はありませんドメインですが、関数の昇格が存在します。この事前分析は次のとおりです:
var a; //関数の宣言a
console.log(a); // undefined
if(true){
function a(){} // function a Define
console.log(a); // function a
}
コードを実際にコピーしますfunction a(){}事前解析後、関数宣言を関数レベルのスコープの前に置き、関数定義をブロックレベルの効果に昇格しますドメインの前面。
注:ここでの関数定義は、ブロックレベルのスコープの最前線に昇格しました。
もう1つの質問:
try {
console.log(a); // undefined
aa.c;
} catch(e){
var a = 1;
}
console.log(a); // 1
console.log(e); //
キャッチないReferenceError:eは定義されていませんキャッチで定義されたコードをコピーしてください。ただし、漁獲量のeには外部からアクセスできません。
catchが「関数スコープ」であると考える場合、a内部を最外部レベルに昇格しないでください。実際、ブロックスコープはキャッチで追跡されます。
JSフィールドには、ブロックレベルのスコープ自体(let constの外)があります。
元の質問をもう一度見てください。
読みやすくするために、件名を再度投稿します:
var a = 0;
if(true){
a = 1;
function a(){}
a = 21;
console.log( "Inside"、a);
}
console.log( "External"、a);
上記で学んだ知識を組み合わせたコードをコピーします。まず、ifで関数a(){}がプロモーションを宣言し、宣言「var a」を関数レベルのスコープの前に移動し、関数定義をブロックレベルのスコープの前に移動します。事前解決は次のとおりです:
var a; / /関数の宣言a
var a = 0; // aの宣言は宣言されており、ここでは無視され、値は直接0に割り当てられます
if(true){
function a(){} //関数定義aの宣言がブロックレベルの前に昇格されます
a = 1; //ここで、ブロックスコープの前にある関数aが1にリセットされます。
//関数a(){};どうやって?
a = 21;
console.log( "inside"、a);
}
console.log( "outside"、a);
コードのコピー関数自体は[関数メモリブロックへの関数名変数ポインタの定義]です。
関数の昇格はブロックレベルのスコープですが、関数名の変数は関数レベルのスコープです。したがって、ブロックレベルの関数定義(元のコード関数宣言位置)の場合、関数名変数は関数レベルのスコープに同期されます。実際には、今回のみ、ブロックレベルのスコープ外で関数定義にアクセスできます。
事前分析は次のとおりです:
var a = 0;
console.log(a、window.a); //出力0および0
if(true){
console.log(a、window.a); //関数の昇格はブロックレベルスコープ、出力関数aおよび0
a = 1; //スコープの最も近いブロックレベルスコープの関数aを受け取り、それは1にリセットされます。これは基本的に変数の割り当てです。
console.log(a、window.a); // aはブロックレベルのスコープを指す、出力1および0
関数a(){} //関数の宣言、関数を実行する変数の定義を関数レベルに同期スコープ。
console.log(a、window.a); // 1と1を出力
するa = 21; //まだ関数定義のブロックスコープの
a、21にリセットconsole.log(a、window.a); / /出力は、機能昇格のブロックレベルスコープのa、出力21、1です。
console.log( "inside"、a);
}
console.log( "outside"、a);

元の記事を28件公開 Likes0 訪問数907

おすすめ

転載: blog.csdn.net/srhgsr/article/details/105499946