重學原生js之變量提高

變量聲明是全部的編程語言中最基礎部分之一。然而,JavaScript 有一個怪異點,稱之爲變量提高(hositing),這個可以讓一個看上去可有可無的聲明變成一個小bug。編程

1、變量提高

在當前上下文遇到一個變量,若是不是私有的,則向上級上下文中查找一直找到全局上下文爲止, 若是全局上下文中也沒有:瀏覽器

  1. 若是是獲取變量的值,則直接報錯

  1. 若是是設置變量的值,則至關於給window(GO)設置一個屬性

2、window全局對象和全局變量的關係

一、二者關係

二者之間存在映射關係(建立一個全局變量,也至關於給window設置一個屬性)編程語言

二、二者優先級

在全局上下文代碼執行的時候,遇到一個變量,首先看是否爲全局變量(若是是操做全局變量,【var/function聲明的會給window也設置一份】),不是全局變量則繼續看是否爲GO的屬性(若是是至關於省略window),若是也不是則按照沒有聲明這個變量的錯誤處理函數

三、window.a爲何是undefined?

直接輸出window.a是對象的成員訪問,哪怕沒有屬性a,屬性值是undefined,也不會報錯spa

3、變量提高練習題

建議從新讀一遍變量提高的概念,再作這三道題。code

第一題

console.log(a); 
var a=12; 
function fn(){
    console.log(a); 
    var a=13;   
}
fn();   
console.log(a);

第二題

console.log(a); 
var a=12;
function fn(){
    console.log(a);
    a=13;
}
fn();
console.log(a);

第三題

console.log(a);
a=12;
function fn(){
    console.log(a);
    a=13;   
}
fn();
console.log(a);

第四題

var foo='hello'; 
(function(foo){
   console.log(foo);
   var foo=foo||'world';
   console.log(foo);
})(foo);
console.log(foo);

解析:對象

一、自執行函數執行:建立一個函數,而且當即把這個函數執行
二、把全局的foo的值'hello'傳遞給私有上下文中的形參
三、函數執行先形參賦值,再變量提高
四、foo已經存在,==不重複聲明==

4、塊級做用域中的變量提高

一、塊級做用域

代碼在執行的時候遇到大括號{}(排除函數、對象的),在看到{}中有let、const、function纔會把其當作塊級做用域。blog

if(true) {
    var a = 1
}
// 不是塊級做用域

if(true) {
    let a = 1
}
// 是塊級做用域

if(true) {
    function a(){}
}
// 是塊級做用域

二、函數在塊級做用域中的變量提高

console.log(foo)
{
    console.log(foo)
    function foo() {}
    foo = 1;
    console.log(foo)
}
console.log(foo);

// undefined  function 1 function

解析:ip

一、{}裏面有function因此是塊級做用域
二、函數在塊級做用域中沒有,因此會變量提高(因此第二個打印function)
三、==重點== 函數出如今塊級做用域中,變量提高階段,只聲明不定義(因此第一個undefined)
四、==重點== 在代碼執行的時候瀏覽器會把function foo()以前的操做,不只認爲是私有的,還會給全局映射一份,以後對foo的操做就認爲是私有的了(因此後兩個分別一、function)

5、塊級做用域變量提高練習題

建議把上面的四句話多讀幾遍再作作用域

第一題

console.log(foo);
{
    console.log(foo);
    function foo() {} // 此時以前對FOO的操做不會映射,等待最後一次再處理
    foo = 1;
    function foo() {}
    console.log(foo);
}
console.log(foo);

第二題

console.log(foo);
{
    function foo() {}
    foo = 1;
    function foo() {}
    foo = 2;
}
console.log(foo);

練習題答案歡迎留言!

公衆號地址,歡迎關注!

相關文章
相關標籤/搜索