1.JavaScript語言的執行流程
編譯階段:構建執行函數;執行階段:代碼依次執行
2.代碼塊:{ ? }
3.變量聲明方式var
有聲明提升,允許重復聲明,聲明函數級作用域
訪問:聲明后訪問都是正常的,在聲明之前訪問值為undefined
(對于變量來說,變量允許使用的范圍被稱為作用域)
<script>//for(表達式1;表達式2;表達式3)//表達式1 執行1次//表達式2 執行n+1次//表達式3 執行n次for(var i = 0;i<10;i++){console.log(i);}debugger;//此處可以訪問到i變量,可以證明var聲明的變量是函數級作用域console.log('循環后輸出i變量的值',i)//10</script>
4. ES6新增的變量聲明方式let
沒有聲明提升,不允許重復聲明但允許重新賦值,聲明塊及作用域?
訪問:聲明前不允許訪問
(變量訪問時,如果當前作用域不存在,則沿作用域向上級作用域查找,找到即返回,直到全局作用域未找到返回undefined)
<script>//console.log('let聲明變量a:',a);//Cannot access 'a' before initializationlet a = 10;// let a = 100;// Identifier 'a' has already been declareda = 100; //允許重新賦值{let a = 100;//此處通過let聲明變量a,作用域僅限于當前代碼塊內部,所以let聲明的變量是塊及作用域console.log('代碼塊中let a=',a);//代碼塊中let a= 100debugger;//用于調試JS代碼}console.log('a',a);//a 100</script>
<script>for(let i = 0;i<10;i++){console.log(i);//1,2,3,4,5,6,7,8,9}console.log('循環后輸出i變量的值',i);//此處訪問的是全局變量i,所以報錯</script>
5.變量聲明方式const
聲明前必須復制,不允許重復賦值,塊級作用域,不存在變量提升
暫時性死區:聲明(編譯階段)到賦值(執行階段)之間的區域被稱為暫時性死區
<script>/*** - JS中的數據類型* - 數值類型* - Number,String,Boolean,Null,Undefined* - 引用類型* - Array,Object* 對于引用類型來說,通過地址修改屬性的值,不是重新賦值* const修飾的是變量的特征,而不是對象的特征*///聲明時必須賦值const a = 10;{const a = 100;console.log(a);//100}//a = 200;//報錯,常量不允許重新賦值console.log(a);//10//對于引用類型來說,變量中存儲的地址改變了,才是重新賦值const obj = {name:'張三',age:18}//通過obj修改了name屬性的值obj.name = '李四';//obj = [4,5,6];//報錯,因為變量的值不能改變console.log(obj);//age:18,name:"李四"</script>
6.函數的聲明方式
6.1new Function()構造函數形式
// new Function()構造函數形式let fn1 = new Function('return 1');console.log(fn1.toString());//function anonymous() {return 1};
6.2function函數聲明
聲明前置(提升),可以在聲明前調用,必須擁有函數名,并且函數名符合標識規范
<script>//function函數聲明fn2();//輸出fn2 executedfunction fn2(){console.log('fn2 executed');return 2;}fn2();//輸出fn2 executed</script>
6.3函數表達式let fn() = function(){}
<script>fn3();//報錯,var fn3相當于變量提升,值為undefind,不是函數不可以調用var fn3 = function(){console.log('fn3 executed');return 3;}fn3();//fn3 executed</script>
6.4立即執行函數表達式(function() {})()
function前面一定要加(),因為function是關鍵字,function如果作為一行的第一個字符,則被認為函數聲明結構
<script>//立即執行函數表達式,是特殊的函數表達式形式,聲明后立即調用,特性與函數表達式方式相同//此處只需要證明function不是第一個字符(function(){console.log('fn4 executed');})();</script>
7.函數參數
函數定義時被稱為形參,函數調用時參數被稱為實參;實參的數量=形參的數量時依次賦值;實參的數量>形參的數量時依次賦值多余的實參被忽略;實參的數量<形參的數量時依次賦值未被賦值的形參為undefined
<script>//形參默認值function fn(a,b,c,d=500){console.log(a,b,c,d);}fn(1,2,3,4);//輸出1,2,3,4//當實參的值為undefined時執行默認值fn(1,2,3,undefined,null);//輸出1,2,3,500</script>
8.剩余參數...args在函數定義時,被稱為剩余函數???????
函數聲明時使用;ES6新特性,用于替換arguments對象?
特征:只能有一個剩余函數;必須是最后一個參數;?是數組,可以使用數組的方法
<script>function add(a,b,...args){console.log(a,b,args);}add(1,2,3,4,5,6,7,8,9,10);</script>
<script>function add(a,b,...args){console.log(a,b,...args);}add(1,2,3,4,5,6,7,8,9,10);//輸出1 2 3 4 5 6 7 8 9 10</script>
?9.延展操作符...變量
可以展開的是可迭代對象(ES6中新增的內容),延展操作符可以展開變量的內容
延展操作符與剩余參數二者格式相同,都是...變量;在函數調用時使用,是延展操作符 ,將可迭代對象展開
<script>function add(a,b){console.log(a,b);}add(1,2);//輸出1,2add([3,4]);//輸出[3, 4] undefined//賦值給a變量,b變量沒有賦值let arr = [3,4];add(...arr);//輸出3,4let str = 'xy';add(...str);//x ylet obj = {name:'zhangsan',age:18}//add(...obj);//報錯//默認情況下,對象不能展開let array = ['a','b','c'];console.log(array);//['a', 'b', 'c']console.log(...array);//a b c//可迭代對象中每一個項作為參數傳遞給函數console.log('a','b','c');//a b c//...array效果相同</script>
10.嚴格模式
就是在代碼的頭部加上use strict????????
在嚴格模式下,函數的arguments和當前函數定義的形參是沒有映射關系,并且禁用arguments.callee和arguments.callee.caller(caller是function的屬性)
arguments變成類數組對象?(特征像數組,擁有length屬性,本質是一個對象)
<script>function fn3(a,b,c){"use strict";//嚴格模式的開關,如果解釋器識別則進入嚴格模式console.log(arguments);console.log(a,b,c);}fn3(4,5,6);</script>
?函數的形參擁有默認值函數內部自動進入嚴格模式?
<script>function fn3(a,b,c=100){console.log(arguments);console.log(a,b,c);}fn3(4,5,6);</script>
兩種代碼輸出結果一致?
??????????????