先談談作用域####
-- 什么是作用域?
就是某個變量有(起)作用的范圍;
--詞法作用域和動態作用域
詞法作用域:在變量聲明的時候,它的作用域就已經確定了;
動態作用域:在程序運行的時候,由程序的當前上下文(執行環境)決定的;
-- js屬于詞法作用域
詞法作用域的訪問規則:
先在當前作用域中查找,如果找到就直接使用,如果沒有找到,那么就到上一級作用域中查找,如果還沒有找到那么就重復這個查找的過程,直到全局作用域
- js中的作用域
(01) script標簽構成的全局作用域;
(02) 在js中,函數是唯一一個可以創建作用域的對象;
var a1 = "a1";
var b1 = "b1";
function func(){
var a1 = "n1";
console.log(a1); //n1(此行a1先在func函數內部作用域中查詢;
console.log(b1); //b1
}
func();
變量和函數的提升####
js的執行過程:
預解析階段 變量和函數的提升(聲明);
具體的執行階段
變量和函數的提升:
js代碼是一個從上至下逐步解析的過程,在這個過程中之前會把所有的的變量和函數提前申明.
console.log(a); //undefined 而不是報錯
var a = 10;
f1(); //f1而不是報錯
function f1(){
console.log("f1");
}
上面一段js代碼,會先把var a與 func函數提前申明,所以代碼實際可用模擬成下面這段代碼:
var a; //變量a提前申明,但未定義
function f1(){//函數提前申明
console.log("f1");
}
console.log(a); //申明未定義,結果為undefined
a = 10;
f1(); //結果為f1
經過上面的解析,結果便可以理解了.
具體會出現的一些問題和幾種情況:
①變量和變量同名的情況:后面的變量會把前面的變量覆蓋;
var n1 = "n1";
console.log(n1); //n1
function test(){
console.log(n1);
}
test(); //n1
var n1 = "new n1"; //覆蓋了之前n1的值
console.log(n1); //new n1
test(); //new n1
②函數和函數同名的情況,后面的函數會覆蓋前面的函數.
f1(); // 20
function f1(){
console.log(10);
}
f1(); //20
function f1(){
console.log(20);
}
f1();//20
③函數和變量同名,可以理解為函數聲明提升而變量的聲明不提升(實際上變量也提升了,但是會被函數覆蓋).
console.log(demo); // demo函數
var demo = "我是字符串";
function demo(){
console.log("我是函數");
}
console.log(demo); //我是字符串
④變量提升是分作用域的
var num=5;
function test1(){
console.log(num);//undefined
var num=10;//此處函數test1作用域中有申明變量num,會提升申明
}
test();
⑤如果函數是函數表達式定義,那么在做函數聲明提升的時候,僅僅只會把var 變量的名稱(函數)提升到當前作用域中.
console.log(func); //undefined
var func = function(){//此處只提升申明var func;所以為undefined;
console.log("func");
}
var func = "我是MT";
console.log(func); //'我是MT'
---自己的學習總結,希望大家喜歡,不足之處歡迎指正,O(∩_∩)O謝謝!