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 initialization
let a = 10;
// let a = 100;// Identifier 'a' has already been declared
a = 100; //允许重新赋值
{
let a = 100;//此处通过let声明变量a,作用域仅限于当前代码块内部,所以let声明的变量是块及作用域
console.log('代码块中let a=',a);//代码块中let a= 100
debugger;//用于调试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 executed
function 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,2
add([3,4]);//输出[3, 4] undefined//赋值给a变量,b变量没有赋值
let arr = [3,4];
add(...arr);//输出3,4
let str = 'xy';
add(...str);//x y
let 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>
两种代码输出结果一致