深切明白 js 變量提拔

我們曉得再
ES5中的
var
function 的申明都存在又變量提拔,
ES6中的
let
const 則不存在有變量提拔。

var變量提拔

console.log(a);
var a =1;

// 等價於

var a ;
console.log(a); // undefined
a = 1; 

js中的 function 也能夠看做是變量,也存在變量提拔

a(); // 1

function a() {
    console.log(1);
}

總之

JavaScript引擎的工作方式是,先剖析代碼,獵取一切被聲明的變量,然後再一行一行地運轉。這形成的效果,就是一切的變量的聲明語句,都會被提拔到代碼的頭部,這就叫做變量提拔(hoisting)。

let深切明白

  • let 聲明的變量的作用域是塊級的;
  • let 不能反覆聲明已存在的變量;
  • let 有臨時死區,不會被提拔。
// case1
var liList = document.querySelectorAll('li') // 共5個li
for( var i=0; i<liList.length; i++){
  liList[i].onclick = function(){
    console.log(i)
  }
}

// case2
var liList = document.querySelectorAll('li') // 共5個li
for( let i=0; i<liList.length; i++){
  liList[i].onclick = function(){
    console.log(i)
  }
}

順次點擊會湧現5個 5 。如果把var 改為了let 就是離別打印0 , 1 , 2, 3, 4 了。

我的明白是:

  1. for(let i = 0; i< 5; i++) 這句話的圓括號之間存在有一個隱蔽的作用域
  2. 再每次實行輪迴體的時刻都會在輪迴體高低文中從新初始化一次
var liList = document.querySelectorAll('li') // 共5個li
for( let i=0; i<liList.length; i++){
  let i = 隱蔽作用域中的i // 看這裏看這裏看這裏
  liList[i].onclick = function(){
    console.log(i)
  }
}
// 那樣的話,5 次輪迴,就會有 5 個差別的 i,console.log 出來的 i 固然也是差別的值。

下面我們再來細緻刨析一下詳細聲明的歷程

var變量聲明的建立、初始化和賦值歷程

function fn(){
    var a = 0;
    var b = 1;
}

fn();

歷程剖析:

  1. 進入fn,為其建立一個環境
  2. 找出fn中一切聲明的變量,在這個環境中建立這些變量(a,b)
  3. 將這些變量初始化為undefined
  4. 最先實行代碼
  5. a 賦值 0,b 賦值 1;

這就詮釋了為何在 var x = 1 之前 console.log(x) 會獲得 undefined。

function的聲明的建立、初始化、和賦值歷程

f2(); // 2

function f2() {
    console.log(2);
}

歷程剖析:

  1. 找到function聲明的變量,在環境中建立
  2. 將這些變量初始化並賦值, function(){ console.log(2) }。
  3. 最先實行代碼 fn(); //2

let聲明的建立、初始化、賦值

{
  let x = 1
  x = 2
}

歷程剖析:

  1. 找到let變量在環境中建立,
  2. 最先實行代碼 ,注重還沒有舉行初始化哦
  3. 實行x = 1; x 初始化為 1
  4. 實行x = 2; x 舉行賦值

我們再來明白一下let 之前不能運用的緣由

{
    console.log(a);
    let a  = 1;
}

緣由:

  1. console.log(a) 中的 a 指的是下面的 a,
  2. 實行 log 時 x 還沒「初始化」,所以不能運用(也就是臨時性死區)

總結

let 的「建立」歷程被提拔了,然則初始化沒有提拔。

var 的「建立」和「初始化」都被提拔了。

function 的「建立」「初始化」和「賦值」都被提拔了。

末了看 const,實在 const 和 let 只要一個區分,那就是 const 只要「建立」和「初始化」,沒有「賦值」歷程。

所謂臨時死區,就是不能在初始化之前,運用變量。

參考文獻

    原文作者:Meils
    原文地址: https://segmentfault.com/a/1190000014401234
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞