let、const与解构赋值
一、let
- es6新增了let命令,用来声明变量,它的用法类似var,但是所声明的变量只在let命令所在的代码块内有效。
{
let a = 'let变量';
var b = 'var变量';
}
console.log(a);//a is not defined
console.log(b);//正确输出
上面代码块,分别用let,var声明了两个变量,在代码块之外调用这两个变量时,let声明的变量就会报错,而var声明的变量正常输出,这说明了let只在它所在的代码块内有效。
- let禁止重复声明
//let声明变量
let num;
//禁止重复声明
let num;//会报错
- 不存在变量声明提升
//不存在变量声明提升
console.log(username);//会报错
let username = "wang";
function fn() {
console.log(username);
let username = "jack";
}
console.log(fn());//会报错
- 支持块作用域
//支持块作用域
if (true) {
var price = 99;
//let price = 50;
}
console.log(price);
let lis = document.querySelectorAll("li");
for (let i = 0; i < lis.length; i++) {
lis[i].addEventListener("click", function () {
console.log("点击了第" + i + "个");
});
}
二、const
- const声明只读变量:常量
//const声明只读变量:常量
//1.const常量,在一个脚本的声明周期内,禁止更新,所以在声明时必须初始化
const NATION = "中国";
//2.不允许重复声明
//const NATION ="CHINA";
//3.支持块作用域
if (true) {
const EMAIL = "wukong@qq.com";
console.log(EMAIL);
}
//console.log(EMAIL);会报错
/*
let 与 const相同之处
1.禁止重复声明
2.支持块作用域
不同之处,let允许更新,而const禁止更新
一种风格就是全部都用const,除非这个数据后期会有改变
可能会更新的或常用的都使用let,除非不会或不太可能被修改的采用const
有一些数据类型强烈推荐使用const
对象或数组
*/
const arr = [1, 2, 3];
console.log(arr);
arr[1] = 20;
console.log(arr);
//arr = ["a","b"]这样更新会报错
const obj = { x: "red", y: "green" };
console.log(obj);
obj.x = "blue";
console.log(obj);
//obj = {};//这样更新会报错,不能直接赋值
const body = document.body;
body.style.backgroundColor = "yellow";
三、var/let/const在全局作用域绑定上的区别
//var 全局
var email = "wukong@qq.com";
console.log(email);
console.log(window.email);
var email = "bajie@qq.com";
console.log(email);
//污染全局环境
//尽量不要创建全局变量,可以创建临时变量
//var role = "custom";
//临时变量就是创建立即执行函数
(function () {
var role = "custom";
})();
//这样就不会显示在全局环境中
//在当前全局环境中创建一个命名空间
//如果在函数对象上添加就是静态成员
var ns = {};
ns.id = 10;
ns.username = "wang";
ns.email = "wang@qq.com";
console.log(window.ns.id, window.ns.username, window.ns.email);
/*------------------------------------------------------*/
//let
let colors = ["red", "green", "blue"];
const BRAND = "HUAWEI";
console.log(colors, BRAND);
//使用let/const声明的变量不会成为全局对象window的属性
console.log(window.colors, window.BRAND); //返回undefined
var name = "hello world";
let name = "hello php";
//let和const声明的变量只会出现在词法作用域/块作用域/静态作用域中
//在全局环境下,var,let,const行为类似
四、解构
//解构主要是针对对象和数组
const obj = { x: 1, y: 2, z: 3 };
/* for (k in obj) {
console.log(k);
} */
//模板解构
//对象
const { x, y, z } = { x: 1, y: 2, z: 3 };
console.log(x, y, z);
//数组
const [a, b, c] = ["a", "b", "c"];
console.log(a, b, c);
//解构的目的:将集合数据按规则打散到一些独立的变量中
//一.传统方式
const product = {
name: "电脑",
price: 5000,
};
let name = product.name;
let price = product.price;
console.log("%s:%c %d", name, "color:red", price);
//二.对象解构
const user = {
username: "wang",
email: "wang@qq.com",
};
//解构语法:解构变量声明 = 要被解构的数据
//let { username, email } 就是结构变量声明
let { username, email } = {
username: "wang",
email: "wang@qq.com",
};
console.log("%s (%s)", username, email);
//1.对象的属性名必须与左边解构变量声明模板中的变量名同名
//2.解构变量必须初始化
let { q, w } = {};
//3.可以将左侧的变量声明看成右侧的赋值模板
//三.解构表达式
let a1 = 10;
let b1 = 20;
console.log(a1, b1);
a1 = 150;
b1 = 300;
console.log(a1, b1);
//换种方式来更新
//1.场景1:用来更新变量
({ a1, b1 } = { a1: 15, b1: 60 });
console.log(a1, b1);
//2.场景2
function out({ m: x, n: y }) {
console.log(x, y);
x = 20;
y = 40;
console.log(x, y);
}
out({ m: 8, n: 8 });
//四.解构声明中设置默认值
let stu = {
stuName: "wang",
gender: "male",
};
let { stuName, gender = "famale", age = 15 } = stu;
console.log(stuName, gender, age);
//五.解构声明中使用变量别名
const book = {
name: "ES6开发指南",
price: 109,
};
let { name: bookname, price: bookprice } = book;
console.log(bookname, bookprice);
五、嵌套对象解构
//对象的属性值也可以是对象或其它复杂类型、
const stu = {
name: "wang",
course: {
php: {
level: "basis",
grade: 80,
},
front: {
level: "advance",
grade: 70,
},
},
};
console.log(stu);
let {
course: { php },
} = stu;
console.table(php);
let {
course: {
php: { level },
},
} = stu;
console.table(level);
let {
course: {
front: { level: frontlevel },
},
} = stu;
console.table(frontlevel);
//多次解构
let {
course,
course: { php: phpinfo },
course: {
php: { level: levelinfo },
},
} = stu;
console.log(course, php, level);
六、数组解构
//数组解构
const [c1, c2, c3] = ["上海", "北京", "广州"];
console.log(c1, c2, c3);
//1.数组解构声明
let user = [1, "admin", "admin@qq.com"];
let [id, name, email] = user;
console.log(id, name, email);
let [, username, ,] = user;
//数组解构和对象解构必须要初始化
console.log(name);
//2.数组解构表达式:更新数组元素
let lesson = "es6";
let grade = 60;
//不要加let,不要加括号([lesson, grade] = ["php", 90]);
[lesson, grade] = ["php", 90];
console.log(lesson, grade);
//3.使用默认值
let [brand, model, color = "red"] = ["huawei", "p40"];
console.log(brand, model, color);
//4.在函数参数中也可以使用数组解构
function add([x, y = 100]) {
return x + y;
}
console.log(add([50, 100]));
console.log(add([100]));
//5.数组嵌套解构
let [a1, a2, [a3, a4], a5] = [10, 20, [30, 40], 50];
console.log(a1, a2, a3, a4, a5);
七、学习总结
1.let
禁止重复声明
不存在变量提升
支持块作用域
2.const
const声明只读变量:常量
const声明变量必须初始化
禁止重复声明
支持块作用域
禁止更新
可能会更新的或常用的都使用let,除非不会或不太可能被修改的采用const
3.var/let/const在全局作用域绑定上的区别
使用var声明的变量会出现在全局环境中
可以用立即执行函数来创建临时变量,这样就不会污染全局环境
(function () {
var role = "custom";
})();
- 也可以创建一个命名空间
var ns = {};
ns.id = 10;
ns.username = "wang";
ns.email = "wang@qq.com";
console.log(window.ns.id, window.ns.username, window.ns.email);
- 使用let/const声明的变量不会成为全局对象window的属性
- let和const声明的变量只会出现在词法作用域/块作用域/静态作用域中
4.解构
解构主要是针对对象和数组
解构的目的:将集合数据按规则打散到一些独立的变量中
解构语法:解构变量声明 = 要被解构的数据
let { username, email } = {username: "wang",email: "wang@qq.com",};
对象的属性名必须与左边解构变量声明模板中的变量名同名
解构变量必须初始化
解构表达式可以用来更新变量
let a1 = 10;
let b1 = 20;
({ a1, b1 } = { a1: 15, b1: 60 });
console.log(a1, b1);
- 解构声明中可以设置默认值
let stu = {stuName: "wang",gender: "male",};
let { stuName, gender = "famale", age = 15 } = stu;
console.log(stuName, gender, age);
- 解构声明中可以使用变量别名
const book = {name: "ES6开发指南",price: 109,};
let { name: bookname, price: bookprice } = book;
console.log(bookname, bookprice);
5.嵌套对象解构
- 对象的属性值也可以是对象或其它复杂类型
const stu = {name: "wang",
course: {
php: {level: "basis",grade: 80,},
front: {level: "advance",grade: 70,},
},
};
let {course: { php },} = stu;
console.table(php);
let { course: { php: { level },},} = stu;
- 多次解构
let {
course,
course: { php: phpinfo },
course: { php: { level: levelinfo },},
} = stu;
console.log(course, php, level);
6.数组解构
数组解构和对象解构必须要初始化
数组解构表达式:可以更新数组元素
let lesson = "es6";
let grade = 60;
//不要加let,不要加括号([lesson, grade] = ["php", 90]);
[lesson, grade] = ["php", 90];
console.log(lesson, grade);
- 也可以使用默认值
let [brand, model, color = "red"] = ["huawei", "p40"];
console.log(brand, model, color);
- 在函数参数中也可以使用数组解构
function add([x, y = 100]) {
return x + y;
}
console.log(add([50, 100]));
console.log(add([100]));
- 数组嵌套解构
let [a1, a2, [a3, a4], a5] = [10, 20, [30, 40], 50];
console.log(a1, a2, a3, a4, a5);