1. let 声明变量
let 声明的变量只在 let 命令所在的代码块内有效
- 块级作用域
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>let 声明变量</title>
</head>
<body>
<ul>
<li>1111</li>
<li>2222</li>
<li>3333</li>
</ul>
<ol>
<li>4444</li>
<li>5555</li>
<li>6666</li>
</ol>
<script>
// 块级作用域
{
let i = 100; // 只存在块内
}
// // 即使在 if for 的块级也只存在于块内
if (true) {
let i = 100;
}
// console.log(i); // Uncaught ReferenceError: i is not defined
// 报错原因是 打印的是块级外部的 i,没有检测到 i 的存在
// var 定义的就不会报错
if (true) {
var i = 100;
}
console.log(i);
// 不管 for 循环内部,外部也可以打印 i
for (var i = 0; i < 5; i++) {
}
console.log(i); // 5
// 弊端:会影响后面的程序
for (let j = 0; j < 5; j++) {
}
// console.log(j); // Uncaught ReferenceError: j is not defined
// 每次 for 循环都是一次新的变量
// 循环内都会记住上一次的值,在上一次的值进行操作,直到完成循环
// 结束后就访问不到 j,不会向外部泄露
// 例:打印出点击 ul 下 的 li 的索引值
// var uli = document.querySelectorAll('ul li');
// for (var i = 0; i < uli.length; i++) {
// uli[i].onclick = function () {
// console.log(i);
// }
// }
// 改进
var uli = document.querySelectorAll('ul li');
for (var i = 0; i < uli.length; i++) {
uli[i].index = i; // 将 i 赋值给每个 li 的索引值
uli[i].onclick = function () {
// console.log(i);
console.log(this.index); // 直接打印相关的 li 索引值
}
}
// let
var oli = document.querySelectorAll('ol li');
for (let i = 0; i < oli.length; i++) {
console.log(i);
// i 在循环中没有被释放,依赖于 for 循环
}
</script>
</body>
</html>
- 不允许重复声明
- 没有变量提升
- 暂存性死区
- 不与顶层对象挂钩
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>let 声明变量</title>
</head>
<body>
<script>
// 不允许重复声明
var a = 1;
var a = 10; // 重复声明
console.log(a); // 10
// let b = 10;
// let b = 20;
// 提示错误:Cannot redeclare block-scoped variable 'b'.
// var c = 10;
// let c = 20;
// 报错
// Uncaught SyntaxError: Identifier 'c' has already been declared
// 没有变量提升
console.log(myname); // 先显示 undefined
var myname = 'ich'; // 变量提升,可以调用再定义,不报错
// console.log(youname);
// let youname = 'du';
// 报错:Uncaught ReferenceError: Cannot access 'youname' before initialization
// 暂存性死区
// let mname = "ich";
// function test() {
// // 暂存性死区
// // 因为 console.log 下面的 mname 不会变量提升,
// // console.log 没有找到 变量 mname
// // 一般情况下,没有找到就会向外部查找相应变量
// // 但是但进入到函数内部时,检测到有 mname,但是没有进行到下一步定义它
// // 所以无法使用 使用 函数内部的 mname,就会导致矛盾,出现报错
// console.log(mname);
// let mname = 'du';
// }
// test()
// 报错:Uncaught ReferenceError: Cannot access 'mname' before initialization
// 不与顶层对象挂钩
var youage = 100;
console.log(window.youage); // 100 与顶层对象挂钩
let myage = 100;
console.log(window.myage); // undefined 不与顶层对象挂钩
</script>
</body>
</html>
2. const 声明常量
不允许被修改
必须初始化
不能重复定义
块级作用域
没有变量提升
不与顶层对象挂钩
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>const 声明常量</title>
</head>
<body>
<script>
// 常量
const myname = 'ich';
// myname = 'du';
// 不允许被修改
// 报错:Uncaught TypeError: Assignment to constant variable
// 必须初始化
// const youname;
// youname = du;
// 报错:'const' declarations must be initialized
// 不能重复定义
// const mname = 'ich';
// const mname = 'du';
// 报错:Uncaught SyntaxError: Identifier 'mname' has already been declared
// 块级作用域
{
const myage = 100;
}
// console.log(myage);
// 报错:Uncaught ReferenceError: myage is not defined
// 没有变量提升
// const youname = 'du';
// function test() {
// console.log(youname);
// const youname = 'panda';
// }
// test();
// 报错原因没有变量提升,进入函数内部打印遇到暂存性死去
// 报错:Uncaught ReferenceError: Cannot access 'youname' before initialization
// 不与顶层对象挂钩
const myage = 100;
console.log(window.myage); // undefined
</script>
</body>
</html>
const 问题
是不是所有 const 修饰的变量都不能被修改?
- 对象里的属性可以被修改
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>const 问题</title>
</head>
<body>
<script>
// 是不是所有 const 修饰的变量都不能被修改?
const myobj = {
name: 'ich',
age: 100
}
// myobj = 'fff'; // 不允许
myobj.name = "du";
console.log(myobj);
// 对象里的属性可以被修改,myobj 是一个地址
// 怎么样才可以使得对象里面的属性不被修改?
// 用 fresze 冻住对象里面的每一个属性
const youobj = Object.freeze({
name: 'du',
age: 100
})
youobj.name = "ich";
console.log(youobj.name); // du 对象里的属性值没有被修改到
</script>
</body>
</html>
3. 解构赋值
3.1 解构数组
使用解构赋值的方式从数组中获取成员
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>变量解构赋值</title>
</head>
<body>
<script>
// 数组解构赋值
let arr = [1, 2, 3];
let [a, b, c] = arr; // 解构赋值,a 赋值 1,b 赋值 2,c 赋值 3
// 两数交换
let x = 1;
let y = 2;
[y, x] = [x, y]
console.log('x = ' + x, 'y = ' + y); // x = 2 y = 1
// 单拿最后一个值
let arr1 = [1, 2, 3];
let [, , e] = arr1;
console.log(e); // 3
// 单拿二维数组中的数组的第一个值
let arr2 = [1, [2, 3, 4], 5, 6];
let [a1, b1, c1] = arr2;
console.log(b1); // [2,3,4]
// 改进
let [a2, [b2], c2] = arr2;
console.log(b2); // 2
// 若要拿 4
let [a3, [, , b3], c3] = arr2;
console.log(b3); // 4
// 设置默认值
let [l] = [];
console.log(l); // undefined,因为没有赋值,所以是 undefined
// 不想 undefined,可以加一个默认值
let [z = 1] = [];
console.log(z); // 1,获得默认值
let [q = 1] = [100]
console.log(q); // 100,默认值被替代
</script>
</body>
</html>
3.2 解构对象
- 解构赋值的方式从对象中获取成员
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>变量解构赋值</title>
</head>
<body>
<script>
// 解构赋值的方式从对象中获取成员
let obj = {
name: 'ich',
age: 100
}
let { name, age } = obj;
console.log(name, age); // ich 100
// 交换两个顺序
let obj1 = {
name1: 'ich',
age1: 100
}
let { age1, name1 } = obj1;
console.log(name1, age1); // ich 100
// 调换顺序还是取一样的,因为是以 k 值来赋值的
// 只取对象中的一个值
let obj2 = {
name2: 'ich',
age2: 100
}
let { age2 } = obj2;
console.log(age2); // 100
// 变量和对象的 k 值重名
// let code = 'AAA';
// let res = {
// code: 200,
// data: '111'
// }
// let { data, code } = res;
// console.log(data);
// 提示报错:Uncaught SyntaxError: Identifier 'code' has already been declared
//
// 解决重名问题:
let code = 'AAA';
let res = {
code: 200,
data: '111'
}
let { data, code: co } = res;
console.log(data, co); // 111 200
// 设置默认值
let code1 = 'AAA';
let res1 = {
code1: 200,
data1: '111'
}
let { data1, code1: co1 , erro = "没有错误"} = res1;
// 没设置默认值,打印的时候回打印 undefined
console.log(data1, co1, erro); // 111 200 没有错误
</script>
</body>
</html>
- 访问对象的 属性 list 的内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>变量解构赋值</title>
</head>
<body>
<script>
// 访问对象的 属性 list 的内容
let code = 'AAA';
let res = {
code: 200,
data: {
list: ['111', '222', '333']
}
}
// 获取 data
let { data, code: co } = res;
console.log(data, co); // 111 200
// 获取 list
let { data: { list } } = res;
console.log(list);
// 获取 list 的内容
let { data: { list: [x, y, z] } } = res;
console.log(x, y, z);
</script>
</body>
</html>
- 使用函数来处理对象,解构对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>变量解构赋值</title>
</head>
<body>
<script>
// 使用函数来处理对象
function getData() {
let res = {
code: 200,
data: {
list: ['111', '222', '333']
}
}
test(res);
test1(res);
test2(res);
test3(res);
}
function test(res) {
console.log(res); // {code: 200, data: {…}}
}
// 打印对象内容
getData();
// 在函数传参部分进行解构
function test1({ code, data }) {
console.log(code, data); // 200 {list: Array(3)}
}
function test2({ code, data: { list } }) {
console.log(code, list); // 200 (3) ['111', '222', '333']
}
function test3({ code, data: { list: [x, y, z] } }) {
console.log(code, x, y, z); // 200 '111' '222' '333'
}
</script>
</body>
</html>
3.3 解构字符串
- 解构赋值的方式从字符串中获取字符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>解构字符串</title>
</head>
<body>
<script>
// 解构字符串
let str = "string";
let [a, b, c] = str;
console.log(a, b, c); // s t r
// 获取字符串长度
let { length } = str;
console.log(length); // 6
// 重名问题
let { length: len } = str;
console.log(len); // 6
</script>
</body>
</html>
4. 模板字符串
ES5 中我们表示字符串的时候使用 ''
或者 ""
在 ES6 中,我们还有一个东西可以表示字符串,就是 ``(反引号)
- 和单引号好友双引号的区别
- 反引号可以换行书写
- 反引号可以直接在字符串里面拼接变量
在 `` 里面的 ${} 就是用来书写变量的位置
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>模板字符串</title>
<style>
.active {
color: red;
}
</style>
</head>
<body>
<ul></ul>
<hr>
<h2>修改后</h2>
<ol></ol>
<script>
// 插入 <li><b>ich</b></li> 的html标签代码
let name = 'ich';
let uli = "<li>\
<b>" + name + "</b>\
</li>"
// 使用了字符串拼接,还有换行的符号
// 写法麻烦
let oli = `<li>
<b>${name}</b>
</li>`
// 支持换行,${} 中可以插入变量
console.log(oli);
let arr = ['ich', 'du', 'ice', 'panda'];
let newlist = arr.map(function (item) {
return `<li>
<b>${item}</b>
</li>`
})
console.log(newlist);
let ul = document.querySelector("ul");
ul.innerHTML = newlist;
// 因为有逗号分隔了
let ol = document.querySelector("ol");
ol.innerHTML = newlist.join(""); // 以空字符串分隔
// 实现添加 class ,并改变第一个 li 的 css 样式
let newlist1 = arr.map(function (item, index) {
return `<li class="${index === 0 ? 'active' : ''}">
<b>${item}</b>
</li>`
})
console.log(newlist1);
ol.innerHTML = newlist1.join("");
</script>
</body>
</html>
GitHub代码
gitee代码