ES6新增的变量声明方式。
// let声明的变量具有块级作用域
{
let a = 1;
console.log(a); // 1
}
// console.log(a); // ReferenceError
// 不存在变量提升
// console.log(b); // ReferenceError
let b = 2;
// 暂时性死区(TDZ)
let x = "outer";
function foo() {
// console.log(x); // ReferenceError
let x = "inner";
}
// 不允许重复声明
let c = 1;
// let c = 2; // SyntaxError
// const声明常量,必须初始化
const PI = 3.14159;
// const E; // SyntaxError
// const声明的变量不能重新赋值
const a = 1;
// a = 2; // TypeError
// 但对象的属性可以修改
const obj = { name: "东巴文" };
obj.name = "db-w.cn"; // 允许
obj.email = "info@db-w.cn"; // 允许
// obj = {}; // TypeError
// 数组同理
const arr = [1, 2, 3];
arr.push(4); // 允许
// arr = []; // TypeError
// 冻结对象
const frozen = Object.freeze({ name: "东巴文" });
// frozen.name = "new"; // 无效(严格模式报错)
// 作用域
var a = 1; // 函数作用域
let b = 2; // 块级作用域
const c = 3; // 块级作用域
// 变量提升
console.log(a); // undefined
var a = 1;
// console.log(b); // ReferenceError
let b = 2;
// 重复声明
var d = 1;
var d = 2; // 允许
let e = 1;
// let e = 2; // SyntaxError
// 全局变量
var f = 1;
console.log(window.f); // 1
let g = 1;
console.log(window.g); // undefined
从数组或对象中提取值。
// 基本用法
const [a, b, c] = [1, 2, 3];
console.log(a, b, c); // 1 2 3
// 跳过元素
const [x, , z] = [1, 2, 3];
console.log(x, z); // 1 3
// 默认值
const [m, n = 10] = [1];
console.log(m, n); // 1 10
// 剩余元素
const [first, ...rest] = [1, 2, 3, 4];
console.log(first, rest); // 1 [2, 3, 4]
// 交换变量
let p = 1, q = 2;
[p, q] = [q, p];
console.log(p, q); // 2 1
// 嵌套解构
const [[a1, a2], [b1, b2]] = [[1, 2], [3, 4]];
console.log(a1, b1); // 1 3
// 基本用法
const { name, age } = { name: "东巴文", age: 25 };
console.log(name, age); // 东巴文 25
// 重命名
const { name: userName, age: userAge } = { name: "东巴文", age: 25 };
console.log(userName, userAge); // 东巴文 25
// 默认值
const { x, y = 10 } = { x: 1 };
console.log(x, y); // 1 10
// 嵌套解构
const { user: { name: n, address: { city } } } = {
user: {
name: "东巴文",
address: { city: "北京" }
}
};
console.log(n, city); // 东巴文 北京
// 剩余属性
const { a, ...rest } = { a: 1, b: 2, c: 3 };
console.log(a, rest); // 1 { b: 2, c: 3 }
// 参数解构
function greet({ name, age = 20 }) {
console.log(`${name}, ${age}岁`);
}
greet({ name: "东巴文" }); // 东巴文, 20岁
// 数组参数
function sum([a, b, c]) {
return a + b + c;
}
console.log(sum([1, 2, 3])); // 6
// 默认值
function fetch(url, { method = "GET", headers = {} } = {}) {
console.log(url, method, headers);
}
fetch("/api/data"); // /api/data GET {}
fetch("/api/data", { method: "POST" }); // /api/data POST {}
增强的字符串语法。
// 基本语法
const name = "东巴文";
const greeting = `Hello, ${name}!`;
console.log(greeting); // Hello, 东巴文!
// 多行字符串
const html = `
<div class="container">
<h1>${name}</h1>
</div>
`;
// 表达式
const a = 1, b = 2;
console.log(`${a} + ${b} = ${a + b}`); // 1 + 2 = 3
// 调用函数
function upper(str) {
return str.toUpperCase();
}
console.log(`${upper("hello")}`); // HELLO
// 标签函数
function tag(strings, ...values) {
console.log(strings); // ["Hello, ", "!"]
console.log(values); // ["东巴文"]
return strings[0] + values[0] + strings[1];
}
const name = "东巴文";
const result = tag`Hello, ${name}!`;
console.log(result); // Hello, 东巴文!
// 实际应用:HTML转义
function safeHtml(strings, ...values) {
let result = "";
for (let i = 0; i < strings.length; i++) {
result += strings[i];
if (i < values.length) {
result += String(values[i])
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">");
}
}
return result;
}
const userInput = "<script>alert('xss')</script>";
console.log(safeHtml`<div>${userInput}</div>`);
// <div><script>alert('xss')</script></div>
展开数组或对象。
// 展开数组
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5];
console.log(arr2); // [1, 2, 3, 4, 5]
// 复制数组
const copy = [...arr1];
console.log(copy); // [1, 2, 3]
// 合并数组
const a = [1, 2];
const b = [3, 4];
const merged = [...a, ...b];
console.log(merged); // [1, 2, 3, 4]
// 函数参数
function sum(x, y, z) {
return x + y + z;
}
const nums = [1, 2, 3];
console.log(sum(...nums)); // 6
// 转换可迭代对象
const str = "hello";
console.log([...str]); // ["h", "e", "l", "l", "o"]
// 展开对象
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 };
console.log(obj2); // { a: 1, b: 2, c: 3 }
// 复制对象
const copy = { ...obj1 };
console.log(copy); // { a: 1, b: 2 }
// 合并对象
const x = { a: 1 };
const y = { b: 2 };
const z = { ...x, ...y };
console.log(z); // { a: 1, b: 2 }
// 覆盖属性
const base = { a: 1, b: 2 };
const extended = { ...base, b: 3, c: 4 };
console.log(extended); // { a: 1, b: 3, c: 4 }
收集多余的参数。
// 收集参数
function sum(...args) {
return args.reduce((a, b) => a + b, 0);
}
console.log(sum(1, 2, 3, 4)); // 10
// 与普通参数结合
function log(level, ...messages) {
console.log(`[${level}]`, ...messages);
}
log("INFO", "用户", "登录成功"); // [INFO] 用户 登录成功
// 只能放在最后
// function wrong(...args, last) {} // SyntaxError
// 数组解构
const [first, second, ...rest] = [1, 2, 3, 4, 5];
console.log(first, second, rest); // 1 2 [3, 4, 5]
// 对象解构
const { a, ...others } = { a: 1, b: 2, c: 3 };
console.log(a, others); // 1 { b: 2, c: 3 }
函数参数默认值。
// 默认参数
function greet(name = "访客") {
console.log(`你好, ${name}!`);
}
greet(); // 你好, 访客!
greet("东巴文"); // 你好, 东巴文!
// 与解构结合
function fetch(url, { method = "GET", headers = {} } = {}) {
console.log(url, method);
}
fetch("/api/data"); // /api/data GET
// 表达式作为默认值
function getValue(value = computeDefault()) {
return value;
}
function computeDefault() {
return "默认值";
}
console.log(getValue()); // 默认值
// 参数有自己的作用域
let x = 1;
function foo(a = x) {
let x = 2;
console.log(a);
}
foo(); // 1(使用外部的x)
// 参数之间可以引用
function bar(a = 1, b = a) {
console.log(a, b);
}
bar(); // 1 1
// 不能引用后面的参数
// function wrong(a = b, b = 1) {} // ReferenceError
简洁的函数语法。
// 基本形式
const add = (a, b) => a + b;
console.log(add(1, 2)); // 3
// 单参数可省略括号
const double = x => x * 2;
console.log(double(5)); // 10
// 无参数
const greet = () => console.log("Hello");
greet();
// 多行语句
const sum = (a, b) => {
const result = a + b;
return result;
};
// 返回对象
const createUser = name => ({ name, created: Date.now() });
console.log(createUser("东巴文"));
// 箭头函数没有自己的this
const obj = {
name: "东巴文",
greet: function() {
setTimeout(() => {
console.log(this.name); // 东巴文
}, 100);
}
};
// 普通函数的this
const obj2 = {
name: "东巴文",
greet: function() {
setTimeout(function() {
console.log(this.name); // undefined
}, 100);
}
};
// 不能用作构造函数
const Foo = () => {};
// new Foo(); // TypeError
// 没有arguments
const foo = () => {
// console.log(arguments); // ReferenceError
};
遍历可迭代对象。
// 遍历数组
const arr = [1, 2, 3];
for (const item of arr) {
console.log(item); // 1 2 3
}
// 遍历字符串
const str = "东巴文";
for (const char of str) {
console.log(char); // 东 巴 文
}
// 遍历Map
const map = new Map([["a", 1], ["b", 2]]);
for (const [key, value] of map) {
console.log(key, value);
}
// 遍历Set
const set = new Set([1, 2, 3]);
for (const item of set) {
console.log(item);
}
// 遍历arguments
function foo() {
for (const arg of arguments) {
console.log(arg);
}
}
foo(1, 2, 3);
// for...of: 遍历值
const arr = [10, 20, 30];
for (const value of arr) {
console.log(value); // 10 20 30
}
// for...in: 遍历键(索引)
for (const key in arr) {
console.log(key); // "0" "1" "2"
}
// for...in会遍历原型属性
Array.prototype.custom = function() {};
for (const key in arr) {
console.log(key); // "0" "1" "2" "custom"
}
// for...of不会
for (const value of arr) {
console.log(value); // 10 20 30
}
掌握了ES6核心特性后,让我们继续学习:
东巴文(db-w.cn) - 让编程学习更简单
🎯 东巴文寄语:ES6是JavaScript的重要更新,let/const、箭头函数、解构赋值、模板字符串等特性已经成为现代JavaScript开发的基础。在 db-w.cn,我们帮你系统掌握ES6!