let
- 没有变量提升
- 有块级作用域
const
- 具有块级作用域
- 没有变量提升
- 常量声明时必须赋值
- 常量赋值后,不能修改
作用:声明常量,常量就是值(内存地址)不能变化的量。
<body>
<script type="text/javascript">
/*
let关键字就是用来声明变量的
使用let关键字声明的变量具有块级作用域
在一个大括号中 使用let关键字声明的变量才具有块级作用域
//var关键字是不具备这个特点的
防止循环变量变成全局变量
使用let关键字声明的变量没有变量提升
使用let关键字声明的变量具有暂时性死区特性
*/
/* --------let关键字就是用来声明变量的-------- */
// let a = 10;
// console.log(a);
/* --------使用let关键字声明的变量具有块级作用域-------- */
if (true) {
let b = 20;
console.log(b)
if (true) {
let c = 30;
}
console.log(c);
}
console.log(b)
/* -------在一个大括号中 使用let关键字声明的变量才具有
//块级作用域 var关键字是不具备这个特点的--------- */
// if (true) {
// let num = 100;
// var abc = 200;
// }
// console.log(abc);
// console.log(num)
/* -------防止循环变量变成全局变量--------- */
// for (let i = 0; i < 2; i++) {}
// console.log(i);
/*-----使用let关键字声明的变量没有变量提升------*/
// console.log(a);
// let a = 100;
/* -------使用let关键字声明的变量具有暂时性死区特性------- */
// var num = 10
// if (true) {
// console.log(num);//报错
// //let num = 20;
// }
</script>
</body>
上面的是let特性展示
下面的是let的坑
<body>
<script type="text/javascript">
var arr = [];
for (let i = 0; i < 2; i++) {
arr[i] = function () {
console.log(i);
}
}
arr[0]();//0
arr[1]();//1
var arr1 = [];
for (var i = 0; i < 2; i++) {
arr[i] = function () {
console.log(i);
}
}
arr1[0]();//2
arr1[1]();//2
</script>
</body>
一个是全局作用域,一个是块级作用域,结果也不同。
全局作用,展示的是全局作用域的值,也就是2.
块级作用域,每次循环都会产生一个块级作用域,每个作用域下的值是不一样的,输出的是每个作用域下的值,所以不同。
// 常量声明后值不可更改
const PI = 3.14;
// PI = 100;
const ary = [100, 200];
ary[0] = 123;//这样改变具体数组下标的值是可以的
ary = [1, 2];//这里会报错
console.log(ary);
//上一行(注释起来)不报错的前提下,这里输出123,200
const常量赋值后不能改变值,(复杂数据类型)但是可以改变其数据结构内部的值。
解构赋值
数组解构
<script type="text/javascript">
// 数组解构允许我们按照一一对应的关系从数组中提取值
//然后将值赋值给变量
let ary = [1, 2, 3];
let [a, b, c, d, e] = ary;
console.log(a);//1
console.log(b);//2
console.log(c);//3
console.log(d);//undefind
console.log(e);//undefind
</script>
对象解构
<script type="text/javascript">
// 对象解构允许我们使用变量的名字匹配对象的属性 匹配成功
//将对象属性的值赋值给变量
let person = {
name: 'lisi',
age: 30,
sex: '男'
};
// let { name, age, sex } = person;
// console.log(name);//lisi
// console.log(age);//30
// console.log(sex);//男
let { name: myName } = person;//这样相当于重命名
console.log(myName); //lisi
</script>
剩余参数
剩余参数语法允许我们将一个不定数量的参数表示为一个数组。
function sum (first, ...args) {
console.log(first); // 10
console.log(args); // [20, 30]
}
sum(10, 20, 30)
剩余参数和解构赋值
let ary1 = ['张三' , '李四', '王五'];
let [s1, ...s2] = ary1;
console.log(s1);//张三
console.log(s2);//['李四', '王五']
箭头函数
定义
() => {}
const fn = () => {}
函数体中只有一句代码,且代码的执行结果就是返回值,可以省略大括号
function sum(num1, num2) {
return num1 + num2;
}
const sum = (num1, num2) => num1 + num2;
如果形参只有一个,可以省略小括号
function fn (v) {
return v;
}
const fn = v => v;
箭头函数中没有argument。
重点
箭头函数不绑定this关键字,箭头函数中的this,指向的是函数定义位置的上下文this。
function fn() {
console.log(this);
return () => {
console.log(this)
}
}
const obj = {
name: 'zhangsan'
};
const resFn = fn.call(obj);//打印一次obj对象
resFn();//打印一次obj对象
//因为fn是箭头函数定义时的位置,所以fn函数的this就是箭头函数的this
<script type="text/javascript">
var age = 100;
var obj = {
age: 20,
say: () => {
alert(this.age)
}
}
obj.say();//弹出100
</script>
这个还是因为this,上面的函数有this,这个箭头函数定义在obj对象上,但是这个obj对象没有自己的this,所以箭头函数的this就是定义是位置的window(obj在window下)
有this就要有作用域,对象这种没有自己的作用域的是没有this的。