做用域

1.做用域概述

一般來講,一段程序代碼中所用到的名字並不老是有效和可用的,而限定這個 名字(變量)的可用性的代碼範圍就是這個名字的做用域,做用域的使用提升了程序邏輯的局部性,加強了程序的可靠性,減小了名字衝突es6

1.1.js做用域(es6以前)分爲: 全局做用域 局部做用域

1.2.全局做用域 :整個script標籤 或者是一個單獨的js文件

var num = 10 ;(這一個標籤是寫在全局做用域裏面 這個變量名是可用的 稱之爲全局做用域)

1.3.局部做用域(函數做用域):在函數內部就是局部做用域,這個代碼的名字只在函數內部起效果和做用

var num = 10  //局部做用域
 function fn(){
  //局部做用域
   var num = 20 ; //局部下的num和全局下的num是不衝突的由於輸出的不同
   console.log(num) //20
 }
 fn()  //切記調用
 console.log(num) // 10

2.變量做用域

在js中,根據做用域的不一樣,變量能夠分爲倆種:全局變量,局部變量

2.1.全局變量:在全局做用域下的變量 在全局下均可以使用(在函數外部定義的變量)(3.特殊狀況注意一下:若是在函數內部,沒有聲明直接賦值的變量也屬於全局變量)

var num=10;
  console.log(num);//能夠打印  10 
  function fn(){ //函數
    console.log(num)//也是能夠打印的 10 
           }
           fn()
            console.log(aru) //4.aru is not defined   不能使用

2.2.局部變量:在局部做用域下的變量 或者能夠理解爲在函數內部的變量就是局部變量(在函數內部定義的變量)(注意:函數的形參也能夠看作是局部變量 4.aru是一個形參)

function fun(aru){
  var num = 10; //1.num就是局部變量 特色就是隻能在函數內部使用
  num = 20; //3 . 若是在函數內部,沒有聲明(不適用var)直接賦值的變量也屬於全局變量
}
fun();
console.log(num);  //2.num is not defined 報錯  因此說外部是不能使用的
console.log(num); //3. 20 若是在函數內部,沒有聲明直接賦值的變量也屬於全局變量

2.3.區別:從執行效率來看全局變量和局部變量
(1)全局變量在任何一個地方均可以使用,只有瀏覽器關閉的時候纔會銷燬,比較佔內存資源
(2)局部變量 當咱們程序執行完畢就會銷燬,比較節約內存資源瀏覽器

3.做用域鏈

3.1.只要是代碼,就至少有一個做用域

var num = 10; //全局做用域函數

3.2.在函數內部的叫作局部做用域

var num = 10;
function fun(){  //外部函數
  var num = 20; 
  function fn(){//3.3.在fun函數裏面有生成了一個fn函數   做用域裏面誕生了一個新的做用域   內部函數
  console.log(num);//3.4.執行是20仍是10呢 20  用鏈式查找決定  它會往上一級找有沒有num 一層一層的找就是鏈式查找
   }
   fn()
}
fun()

3.3.若是函數中還有函數,那麼在這個做用域中就有能夠誕生一個做用域

3.4.根據在內部函數能夠訪問外部函數變量的這種機制,用鏈式查找決定哪些數據能被內部函數訪問,就稱爲做用域鏈(簡單理解就是就近原則,誰離的近就執行誰)

案例1:

function f1(){   //1  能夠稱爲0級鏈
  var num = 123;    //2  能夠稱爲1級鏈
  function f2(){    //2  能夠稱爲1級鏈
     console.log(num);    //3 能夠稱爲2級鏈       123
  }  
  f2()
}
var num = 456;  //1 能夠稱爲0級鏈
f1();

案例2:

var a = 1;
 function fn1(){
    var a = 2;
    var b = '22';
    fn2();
    function fn2(){
       var a = 3;
       fn3();
       function fn3(){
          var a = 4;
          console.log(a);   //4
          console.log(b);   //22
        }
    }
  }
 fn1();

2、預解析

.1問

console.log(num) //num is not defined

.2問

console.log(num) //undefined   坑1
var num = 10; 
~ //至關於執行了如下代碼 
var num;
console.log(num);  //只聲明不賦值  因此輸出就是 undefined
num = 10;

.3問(直接函數聲明 利用關鍵字來進行聲明)

function fn(){
  console.log(11)  //11  
}
fn();

.4問 (函數表達式採用了表達式賦值形式 這裏使用function賦值的沒辦法進行函數提高)

//fun()  //若是放到上面調用呢   undefined  坑2
var fun  = function(){   
  console.log(22) //22  
}
fun() 
~//至關於執行了如下代碼 
var fun;     //只聲明不賦
fun();      //沒有這個函數調用確定會報錯  因此正確寫法是將fun寫到後面
fun = function(){   //函數表達式
  console.log(22) //22  
}
fun();

1.什麼是預解析

js代碼是由瀏覽器中的js解析器來執行的,js解析器在運行js代碼的時候分爲倆步:預解析和代碼執行

1.1.預解析 : js引擎會把js 裏面全部的var 還有function 提高到當前做用域的最前面

1.2.代碼執行 : 按照代碼的書寫順序從上往下執行

2.預解析分爲 變量預解析(變量提高) 和 函數預解析(函數提高)

2.1.變量提高 就是把全部的變量聲明提高到當前的做用域最前面 不提高賦值操做

2.1.函數提高 就是把全部的函數聲明提高到當前做用域的最前面 不調用函數(函數表達式 調用必須寫在函數表達式下面)

相關文章
相關標籤/搜索