<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                js中變量的處理機制,你是否想了解下,想的話上車!!! 在聊到變量提升的時候,我們先聊下`LHS`和`RHS` ## 1、`LHS`、`RHS` >`javascript`中兩種查找類型,含義是賦值操作的左側和右側 * `LHS`: 對那個賦值對那個進行`LHS`引用,可以理解為賦值操作的目標 如:`a = 2`,如果找不到在非嚴格模式會聲明一個全局變量 * `RHS`: 需要獲取那個變量的值,就對哪個變量進行`RHS`引用,理解為賦值操作的源頭,如果找不到對應的標識符,就會拋出異常:`ReferenceError` **簡單的講:賦值就是`LHS`,找值就是`RHS`** 來個例子分析分析: ``` function foo(a) { var b = a; return b + a; } var c= foo() ``` 以上代碼有3個`LHS`和4個`RHS`,分析如下: * 1、`var c`中需要被賦值,在賦值操作的左側,所以對c進行`LHS`引用 * 2、變量`c`需要被賦值,它的值是`foo(2)`,那么`foo(2)`的值是多少呢?,需要查找`foo(2)`的值,在賦值操作的右側,所以對`foo(2)`進行`RHS`引用 * 3、隱含賦值操作,將`2`傳遞給`function foo(a){...}`函數的參數`a`,`a`在賦值操作的左側,對`a`進行`LHS`引用 * 4、`var b = a`,`b`需要被賦值,處于賦值操作的左側,所以對`b`進行`LHS`引用,`b`的值是`a`,那么`a`是多少呢,需要對`a`進行`RHS`引用 * 5、`return b + a`中,需要找到`a`和`b`的來源,`a`和`b`都在賦值操作的右側,對`b + a`進行`RHS`引用 ## 2、變量提升 >`js`中變量提升到當前作用域的頂部,而賦值操作在原處不變 舉個例子: `console.log(a) ;var a = 2;`輸出的值是什么? 很多人可能會報錯`ReferenceError`,但是不是,后面定義了`a`,所以變量會提升,就是在`console.log(a)`前面多寫了一行代碼`var a`,如果是`console.log(a); a = 2;`沒有`var`的情況下,會報`//ReferenceError: a is not defined` 再來一個例子: ``` var name="Bob"; (function(){ ????if(typeof name=== 'undefined'){ ????????var name='Jack';//此處增加name聲明 // name = 'Jack' // 輸出:hello,Bob ????????console.log('Goodbye'+name); ????}else{ ????????console.log('hello'+name); ????} })() // 輸出:Goodbye Bob ``` 修改一下: ``` (function(){ ? ? ? ? ? ?name='Jack'; ? ? ? ? ? ?if(typeof name=== 'undefined'){ ? ? ? ? ? ? ? ? console.log('Goodbye'+name); ? ? ? ? ? ? }else{ ? ? ? ? ? ? ? ? console.log('hello'+name); ? ? ? ? ? ? } ? ? })(); // hello Jack ``` ?console.log("name:"+name);// name:Jack?(未使用var,默認聲明為全局變量) 注意:多個`script`不可以跨越 ``` <script> console.log(a) </script> <script> var a = 1; </script><br> // 控制臺報錯`ReferenceError: a is not defined ``` ## 3、函數提升 變量提升了,那么函數的聲明也會提升。 **函數的聲明有兩種方式:** * 1、命名函數式 ``` // 聲明式 function foo() { ..... } ``` * 2、函數字面量式(即函數表達式) ``` // 字面量式 var foo = function() { ..... } ``` 那么重點來了,先看例子: ``` console.log(bar); // f bar() { console.log(123) } console.log(bar()); // undefined var bar = 456; function bar() { console.log(123); // 123 } console.log(bar); // 456 bar = 789; console.log(bar); // 789 console.log(bar()) // bar is not a function ``` 相當于: ``` // js執行步驟 // 函數提升,函數提升優先級高于變量提升 var bar = function() { console.log(123) }; // 變量提升,變量提升不會覆蓋(同名)函數提升,只有變量再次賦值時,才會被覆蓋 var bar; console.log(bar); console.log(bar()); // 變量賦值,覆蓋同名函數字面量 bar = 456; console.log(bar); // 再次賦值 bar = 789 console.log(bar); console.log(bar()); ``` 兩個例子得到的結果: ``` // js執行結果 f bar() { console.log(123) } 123 // 執行bar()里的console.log undefined // bar()的返回值,如果函數沒有返回值,默認為:undefined 456 789 [typeError]:bar is not a function ``` **得出結論:** >函數的提升優先級高于變量的提升,且不會被同名變量聲明時覆蓋,但是會被變量賦值后覆蓋 ### ???那么命名函數和字面量式函數的提升有什么不同呢? * 1、先看命名函數式 ``` foo() // 1 function foo() { console.log('1') } ``` 說明命名函數式的函數本身也會提升到當前作用域的最前面 * 2、再看下字面量式(表達式): ``` foo() // Uncaught TypeError: foo is not a function, 此時的foo為undefined var foo = function() { console.log('1') } <=>相當與以下代碼 var foo foo() foo = function() { console.log('1') } ``` 注意:同名函數聲明,則覆蓋之前的函數聲明 ``` foo() // 4 function foo() { console.log('3') } function foo() { console.log('4') } ``` 但是同名不同形式的聲明方式是不一樣的 ``` foo() // 3 函數提前不覆蓋 function foo() { console.log('3') } var foo = function() { console.log('4') } foo() //4 覆蓋前面的方法 ``` 最后用一個面試題結尾: ``` function Foo() { getName = function () { alert (1); }; return this; } Foo.getName = function () { alert (2);}; Foo.prototype.getName = function () { alert (3);}; var getName = function () { alert (4);}; function getName() { alert (5);} //請寫出以下輸出結果: Foo.getName(); // 2 => Foo的靜態屬性getName getName(); // 4 => 執行全局環境下的getName Foo().getName(); // 1 <=>window.getName() getName(); // 1 => 執行全局環境下的getName new Foo.getName(); // 2 => 執行Foo的靜態屬性getName的構造函數 new Foo().getName(); // 3 相當于Foo實例原型上的getName new new Foo().getName(); // 3 相當于Foo實例原型上的getName的構造函數 ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看