JS変数アップ

13028 ワード

1.変数アップの概念
変数アップグレードの概念:スタックメモリ(作用領域)が形成されると、JSコードが上から下まで実行される前に、ブラウザはまず、すべてのベルトvar / functionのキーワードの先頭を事前に宣言または定義する.このような事前処理機構を「変数アップ」と呼ぶ.
ステートメント(declare):var a(デフォルトundefined)定義(defined):a = 12(定義は実際には値付け操作)
変数アップグレードフェーズ:-バンドvarは、アップグレードステートメントのみが定義されていません(デフォルト値undefinedへ)-バンドfunctionは、リフティングステートメントと定義が完了しました.
console.log(a); //=> undefined,         ,      
var a = 12;

b(); //=> 1,      ,        ,     
function b() {
  console.log(1);
}
functionキーワードで宣言された関数は、変数アップグレード段階で既に値が与えられていますので、JSファイルの任意の位置でこの関数を呼び出すことができます.
変数の理解を深める
変数の昇格は、現在のスコープがページの読み込みを開始したときにのみグローバルスコープで変数の昇格を行います.このとき、関数に格納されているのは文字列だけです.
グローバルスコープで宣言された関数または変数は大域変数であり、同じ原理で、プライベートスコープで宣言された変数はプライベート変数である.
コード実行時に、アップグレードされた声明をスキップし、ブラウザを定義するのは怠惰です.したことは二回目の実行を繰り返しません.つまり、コード実行が関数を作成する部分のコードに出会ったら、直接スキップすればいいです.変数宣言に遭遇した場合は、直接に宣言をスキップして、割り当てを行います.アップグレード段階では変数の宣言と関数の割り当てが完了しているからです.
関数が実行され、プライベートスコープが形成された後、変数がプライベートスコープ形成を向上させた後、先にモジュラス値を行い、その後変数のアップグレードを行います.
ES 5におけるスコープはES 5シンタックス仕様において、大域的スコープと関数のみが実行するプライベートスコープであり、他の大かっこはスタックメモリを形成しない.
2.varを持つか、varを持たないかの違い
グローバルスコープで変数を宣言すると、var/functionのグローバルオブジェクトにも相当する属性が設定されています.変数値は属性値です.プライベート・スコープで宣言されたプライベート変数は、windowとは関係がない.
a; //=> undefined
window.a; //=> undefined
'a' in window; //=> true        ,               a,       a         window   ,          a   ,     undefined

var a = 12; 
a; //=>      a 12
window.a; //=> window     a 12

//=>       window           
a = 13;
window.a; //=> 13
window.a = 14;
a; //=> 14
グローバルスコープにおいて:windowを持たないときは、本質的にはvarに属性を追加し、読み出し属性において、まず変数かどうかを検出し、変数であればその値を読み取り、変数でない場合はwindowの属性を読み出し、windowもこの属性がない場合はエラーが発生する.
a; //=>   
window.a; //=> undefined,       ,          undefined
'a' in window; //=> false,   window     a
a = 12; //=>     window.a = 12,    a     ,   window    
a;//=> 12
window.a; //=> 12
var a = 12, b = 13; 
//=>    b    var  ,    var a = 12; var b = 13;
var a = b = 12;
//=>    b    var  ,    var a = 12; b = 12;

console.log(a, b); //=> undefined undefined
var a = 12, b = 12;
function fn() {
  console.log(a,b); //=> undefined 12
  var a = b = 13;
  console.log(a, b); //=> 13, 13
}
fn();
console.log(a,b); //=> 12, 13
プライベートスコープでは、-プライベートスコープ変数のアップグレード段階では、すべてのプライベート変数として宣言されています.外部との関係はありません.
function fn() {
  b = 12;
  'b' in window;
  //=> true,          ,            window         ,       window         b
  console.log(b); //=> 12
}
fn();
console.log(b); //=> 12,        window    
具体的な分析:
a(); //=> f    
var a = 10;
var a = 20;
console.log(a) //=> 20
a(); //=>   ,   a=20,    
function a() {
  console.log(a);
}
/*
 *       :
 * var a; function a = xxxfff000
 *     
 * a() --> a   ,     a,         
 * a = 10; -->       a          10
 * a = 20; -->       a     10      20
 * console.log(a); -->      20
 * a() --> a   ,    20(),    ,      :a is not a function
 */
fn();// 15
var n = 13;
console.log(n); // 13
fn(); // 15
console.log(n);//15
function fn(){
  n = 15;
  console.log(n);
}
fn(); // 15
alert(n);//15
//           n :undefined
// fn()           n : 15
// n = 13;        n : 13
// fn()           n : 15
3.変数アップの特殊な場合
(1)等号の右側は変数の引き上げが行われません.
fn(); //=>     ,    
a(); //=>     ,         ,   a is not a function
f(); //=>    ,  ,f is not defined
var a = function f(){}
function fn() {}
(2)条件文における変数の昇格-windowに影響がない場合、条件が成立するかどうかに関わらず変数の昇格を行います.varに対して特別な比較をします.-古いバージョンのブラウザレンダリングメカニズムの下で、ステートメントの定義はすべて昇格します.すべては声明だけを昇格させて、定義がなくて、類似したfunction
console.log(sum2,sum3); //=> undefined undefined
console.log(f,g); //=> undefined undefined
if(1 > 2){
  var f = 12;
  function sum2() {
    console.log(12)
  }
} else {
  var g = 14;
  function sum3() {
    console.log(13);
  }
}
console.log(sum2,sum3); //=> undefined f:function sum3(){}
console.log(f,g); //=> undefined 14
条件が成立したら、判定体に入ります.第一の件はコード実行ではなく、変数アップと同じように関数を定義します.つまり、体のコード実行前に、函数はすでに割り当てられました.
console.log(fn); //=> undefined
if (1 === 1) {
  console.log(fn); //=>     
  function fn() {
    console.log(1);
  }
}
(3)匿名関数、自己実行関数、等号右関数、varから戻ってきた関数には変数はありません.最初にreturnで宣言した変数を直接使用して昇格させるしかありません.
//=>        ,       
(function(){

})()

var a = function() {}

obj.onclick = function(){}

function a() {
  //=> e     
  return function e() {

  }
}
(4)関数の形参加変数の昇格
var a=12;
function fn1(){
  console.log(a);
  var a=13;
}
fn1(); //=> undefined

var n=13;
function fn2(n){
  //                    ,      
  // n = 13
  // var n    n       ,   13
  // console.log(n); //13
  console.log(n);
  var n=14;
  console.log(n);
}
fn2(n);//=> 13 14
4.重名問題の処理
  • functionおよびvarキーワード宣言の名前は、変数であり、格納されている値だけが異なる.同じ名前をつけても、名前は
  • です.
  • リネームについての処理:名前が重複していると再声明はしませんが、変数のリフティング段階もコードの実行段階も再定義されます.
  • 変数が上昇したときに、変数の値がないと、そのデフォルトの値functionになります.すでに値があるなら、このステップは実行されません.
    /*
     *       
     * function a   ,    var a   ,      ,     
     * /
    function a() {
      console.log(a);
    }
    var a = 12;
    /*
     *       
     *              ,     ,             
     *
     *                、       
     * 
     */
    fn(); //=> 4
    function fn() {console.log(1);}
    fn(); //=> 4
    function fn() {console.log(2);}
    fn(); //=> 4
    var fn = 100;
    fn(); //=>   ,fn is not a function
    function fn() {console.log(3);}
    fn();
    function fn() {console.log(4);}
    fn();