js中的作用域與預(yù)解釋

在開始之前先寫一下js中的數(shù)據(jù)類型
. 基本數(shù)據(jù)類型 number, boolen ,string ,null, undefined
. 對象數(shù)據(jù)類型 object {} [] /$/,date (對象,數(shù)據(jù),正則,日期) ,function

拋出問題:

    console.log(num);
    console.log(fn);
    console.log(fn());

    var num =12 ;
    var obj ={
        name: "rapheal",
        age:"20"
    }
    function fn(){
        console.log("我是執(zhí)行結(jié)果");
        return "";
    }

    console.log(num);
    console.log(fn);
    console.log(fn());

執(zhí)行結(jié)果是

圖片.png
  1. 為什么第一次num 是 undefined 而 fn 不是?

作用域

書面解釋: 作用域是指程序源代碼中定義變量的區(qū)域。我覺得更好的解釋是內(nèi)存中開辟的一段內(nèi)存空間。
函數(shù)的作用域在函數(shù)定義的時候就決定了。(不理解后面會有解釋)

當html頁面加載的時候,瀏覽器首先會提供一個全局的js 執(zhí)行的作用域, 也就是 window 對象(NODE的 global對象)

預(yù)解釋
預(yù)解釋 也叫變量提升

在當前作用域中在js 執(zhí)行之前,瀏覽器會默認的先把所有var 和function 進行提前聲明或者定義

(1)聲明和定義
聲明: var num ; 告訴當前作用域有一個num 的對象; 但是該對象是沒有定義的是undefined;
定義:給變量賦值 num = 12;

(2)var和 function 在預(yù)解釋的時候進行的操作上還是不一樣的,
var在在預(yù)解釋的時候只進行了變量聲明
function 在預(yù)解釋的時候 聲明和定義都完成了

到目前為止 就能解釋 文章開始的時候提出的問題了。。。

(3) 預(yù)解釋 只發(fā)生在當前作用域下面,頁面開始的時候只對window 下面的進行預(yù)解釋,函數(shù)內(nèi)部的 代碼只有執(zhí)行的時候才開始預(yù)解釋

預(yù)解釋的特點

  1. 預(yù)解釋中如果有條件,無論條件是否成立,都會把 帶var 的變量進行提前聲明 如下demo 輸出的 undefined
  if(!('num' in window)){
        var num =12 ;
    }
    console.log(num); // 輸出 undefined
  1. 預(yù)解釋的時候只預(yù)解釋 '='左邊的,右邊的是值不參與預(yù)解釋
//    fn2();  //Uncaught TypeError: fn2 is not a function
//    var  fn2 =function () {
//        console.log('fn2');
//    }
//    fn();
//    function fn() {
//        console.log('fn');
//    }
//    fn();

3.自自行函數(shù)在全局作用域下不進行預(yù)解釋,當代碼執(zhí)行到位置的時候定義和執(zhí)行一起完成

4.函數(shù)體 return 下面的代碼雖然不執(zhí)行,但是需要進行預(yù)解釋,return 后面跟的都是我們的返回值,所有不進行定義

 function fn3() {
        console.log(num3);  //=> undefined
        return function () {

        };
        var num3 = 100;
    }
    fn3();

作用域

剛才說頁面加載 js 代碼執(zhí)行的時候 會有一個全局的作用域。
私有作用域: 函數(shù)執(zhí)行的時候會生成一個私有的作用域。

全局變量: 在全局作用域下聲明的變量是全局變量
私有變量: 在"私有作用域的聲明的變量"和"函數(shù)的形參"都是私有變量

作用域鏈:在私有作用域中,我們的代碼執(zhí)行的時候遇到一個變量,首先我們需要確定它是否是私有變量,如果是私有變量,那么和外面的沒有任何關(guān)系,如果不是私有的,則往當前作用域的上級作用域查找,如果上級作用域也沒有則繼續(xù)查找,一直找到window 為止 ;,,,,(作用域鏈)

作用域特點
(1) 在全局作用域中,帶var 和不帶var 的區(qū)別

// 區(qū)別 :帶var 的是可以進行預(yù)解釋的,所以在賦值前面執(zhí)行不會報錯,不帶var 的是不能進行預(yù)解釋的,在前面執(zhí)行會報錯;
// 關(guān)系: num2=12 =》 相當于給window 增加了一個叫做num2的屬性名,屬性值是12

console.log(num);  //undefined                                      
console.log(num2);  //Uncaught ReferenceError: num2 is not defined  
var num=1;                                                          
  num2 = 10;                                                        

(2)私有作用域中出現(xiàn)一個不是私有的變量,則往上級作用域查找,一直找到window 為止,如果window 下也沒有,會在window 作用域增加一個變量

function fn() {         
    console.log(total); 
    total =10;          
}                       
fn();                   

(3)看當前函數(shù)是在哪個作用域下定義的,那么他的上級作用域就是誰 和函數(shù)在哪執(zhí)行的沒有任何關(guān)系

 var num = 12;
    function fn() {
        var num =120;
        return function () {
            console.log(num);
        }
    }
    var f= fn();
    f();
    !function () {
      var num = 1200;
        f();
    }()

先寫這么多吧,有什么問題大家一塊討論。。。。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容