摘要:變量提升原理引擎的工作方式是先解析代碼,獲取所有被聲明的變量然后在運行。代碼自上而下執(zhí)行之前,瀏覽器首先會把所有帶關鍵詞的進行提前聲明或者定義,這種預先處理機制稱之為變量提升。
變量提升
原理:JS引擎的工作方式是先解析代碼,獲取所有被聲明的變量;然后在運行。JS代碼自上而下執(zhí)行之前,瀏覽器首先會把所有帶 “VAR”/“FUNCTION” 關鍵詞的進行提前 “聲明” 或者 “定義” ,這種預先處理機制稱之為 “變量提升”。
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
undefined undefined:首先輸出這個結果是因為變量提升,即前三行變成
var a; var b; console.log(a,b);//undefined undefined a = 12; b = 12;
undefined 12:接下來執(zhí)行函數(shù)fn(fn一開始也被執(zhí)行了變量提升,只不過函數(shù)中存儲的都是字符串而已),對fn內部進行分析,即內部代碼變成:
var a; console.log(a,b);//undefined 12 a = 13; b = 13; //不加var的本質是WIN的屬性,即相當于window.b = 13; console.log(a,b);//13 13
一開始b在fn內部找不到,便會開始往上一層找,找到了全局的b,于是b輸出12。
當經過var a = b = 13; 后,b被賦值為13,于是輸出先從函數(shù)內部找b,找到了b=13,第二次輸出b為13。(!同時,最先定義的全局變量b = 12也被賦值為13,故最后的b也等于13)
私有作用域中帶var和不帶var的區(qū)別:只對等號左邊進行變量提升
1.帶var的在私有作用于變量提升階段,都聲明為私有變量,和外界沒有任何的關系
2.不帶var不是私有變量,會向它的上級作用于查找,一直找到window為止(這種查找機制叫做:“作用域鏈”),也就是在私有作用域中操作的這個非私有變量,是一直操作別人的
sum(); fn();// Uncaught TypeError: fn is not a function //=>匿名函數(shù)之函數(shù)表達式 var fn = function(){ console.log("fn"); }//=>代碼執(zhí)行到此處會把函數(shù)值賦值給fn //=>普通的函數(shù) function sum(){ console.log("sum"); }條件判斷下的變量提升
/* * 在當前作用域下,不管條件是否成立都要進行變量提升 * =>帶VAR的還是只聲明 * =>帶FUNCTION的在老版本瀏覽器渲染機制下,聲明和定義都處理,但是為了迎合ES6中的塊級作用 * 域,新版瀏覽器對于函數(shù)(在條件判斷中的函數(shù)), * 不管條件是否成立,都只是先聲明,沒有定義,類似于var */ console.log(a);//undefined if(1 === 2){ var a = 3; } console.log(a);//undefined重名問題的處理
fn();//=>4 function fn() {console.log(1);} fn();//=>4 function fn() {console.log(2);} fn();//=>4 var fn=100;//=>帶VAR的在提升階段只把聲明處理了,賦值操作沒有處理,所以在代碼執(zhí)行的時候需要完成賦值 FN=100 fn();//=>100() Uncaught TypeError: fn is not a function function fn() {console.log(3);} fn(); function fn() {console.log(4);} fn();
帶VAR和FUNCTION關鍵字聲明相同的名字,這種也算是重名了(其實是一個FN,只是存儲值的類型不一樣)
關于重名的處理:如果名字重復了,不會重新的聲明,但是會重新的定義(重新賦值)[不管是變量提升還是代碼執(zhí)行階段皆是如此]
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/106335.html
摘要:執(zhí)行上下文和執(zhí)行棧是中關鍵概念之一,是難點之一。理解執(zhí)行上下文和執(zhí)行棧同樣有助于理解其他的概念如提升機制作用域和閉包等。函數(shù)執(zhí)行完成,函數(shù)的執(zhí)行上下文出棧,并且被銷毀。 前言 如果你是一名 JavaScript 開發(fā)者,或者想要成為一名 JavaScript 開發(fā)者,那么你必須知道 JavaScript 程序內部的執(zhí)行機制。執(zhí)行上下文和執(zhí)行棧是JavaScript中關鍵概念之一,是Ja...
摘要:執(zhí)行上下文和執(zhí)行棧是中關鍵概念之一,是難點之一。理解執(zhí)行上下文和執(zhí)行棧同樣有助于理解其他的概念如提升機制作用域和閉包等。函數(shù)執(zhí)行完成,函數(shù)的執(zhí)行上下文出棧,并且被銷毀。 前言 如果你是一名 JavaScript 開發(fā)者,或者想要成為一名 JavaScript 開發(fā)者,那么你必須知道 JavaScript 程序內部的執(zhí)行機制。執(zhí)行上下文和執(zhí)行棧是JavaScript中關鍵概念之一,是Ja...
摘要:本計劃一共期,每期重點攻克一個面試重難點,如果你還不了解本進階計劃,點擊查看前端進階的破冰之旅本期推薦文章深入之執(zhí)行上下文棧和深入之變量對象,由于微信不能訪問外鏈,點擊閱讀原文就可以啦。 (關注福利,關注本公眾號回復[資料]領取優(yōu)質前端視頻,包括Vue、React、Node源碼和實戰(zhàn)、面試指導) 本周正式開始前端進階的第一期,本周的主題是調用堆棧,今天是第二天。 本計劃一共28期,每期...
摘要:原文鏈接變量對象是說的執(zhí)行上下文中都有個對象用來存放執(zhí)行上下文中可被訪問但是不能被的函數(shù)標示符形參變量聲明等。對于函數(shù)的形參沒有什么可說的,主要看一下函數(shù)的聲明以及變量的聲明兩個部分。 首先明確幾個概念: EC:函數(shù)執(zhí)行環(huán)境(或執(zhí)行上下文),Execution Context ECS:執(zhí)行環(huán)境棧,Execution Context Stack VO:變量對象,Variable Obj...
摘要:會出現(xiàn)這樣的情況是因為擁有暫時性死區(qū)。規(guī)定暫時性死區(qū)和語句不出現(xiàn)變量提升,主要是為了減少運行時錯誤,防止在變量聲明前就使用這個變量,從而導致意料之外的行為。 首先我們應該知道js引擎在讀取js代碼時會進行兩個步驟: 第一個步驟是解釋。 第二個步驟是執(zhí)行。 所謂解釋就是會先通篇掃描所有的Js代碼,然后把所有聲明提升到頂端,第二步是執(zhí)行,執(zhí)行就是操作一類的。 我們先來看個簡單的變量提升...
閱讀 1030·2021-09-22 15:26
閱讀 2607·2021-09-09 11:52
閱讀 1890·2021-09-02 09:52
閱讀 2241·2021-08-12 13:28
閱讀 1180·2019-08-30 15:53
閱讀 506·2019-08-29 13:47
閱讀 3380·2019-08-29 11:00
閱讀 3095·2019-08-29 10:58