js中的作用域與預解釋

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

拋出問題:

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

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

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

執行結果是

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

作用域

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

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

預解釋
預解釋 也叫變量提升

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

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

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

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

(3) 預解釋 只發生在當前作用域下面,頁面開始的時候只對window 下面的進行預解釋,函數內部的 代碼只有執行的時候才開始預解釋

預解釋的特點

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

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

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

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

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

作用域

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

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

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

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

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

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

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

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

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

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

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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容