JavaScript 基础与 ES6+ 新特性

时游大约 3 分钟

JavaScript 基础与 ES6+ 新特性

JavaScript 是 Web 开发的核心语言。ES6 (ECMAScript 2015) 及其后续版本引入了大量新特性,极大地提升了开发效率和代码可读性。

变量声明 (let & const)

ES6 引入了 letconst 来替代 var

  • let: 块级作用域,不存在变量提升,不允许重复声明。
  • const: 块级作用域,声明常量,一旦声明必须初始化,且值不能重新赋值(但对象属性可修改)。
// var 的问题:变量提升,没有块级作用域
if (true) {
    var a = 10;
}
console.log(a); // 10

// let 的块级作用域
if (true) {
    let b = 20;
}
// console.log(b); // ReferenceError: b is not defined

// const 常量
const PI = 3.14159;
// PI = 3.14; // TypeError: Assignment to constant variable.

const person = { name: "Alice" };
person.name = "Bob"; // OK: 修改对象属性是允许的

Symbol (基本数据类型)

ES6 引入的原始数据类型,表示独一无二的值。常用于定义对象属性名,避免冲突。

const s1 = Symbol('foo');
const s2 = Symbol('foo');
console.log(s1 === s2); // false

const obj = {
    [s1]: 'Hello'
};
console.log(obj[s1]); // Hello
// Symbol 属性不会出现在 for...in、Object.keys() 中

箭头函数 (Arrow Functions)

箭头函数提供了一种更简洁的函数写法,并且不绑定自己的 this

// 传统写法
const sum = function(a, b) {
    return a + b;
};

// 箭头函数
const sumArrow = (a, b) => a + b;

// 箭头函数的 this
const obj = {
    name: "MyObj",
    sayHello: function() {
        setTimeout(() => {
            console.log(`Hello from ${this.name}`); // this 指向 obj
        }, 1000);
    }
};
obj.sayHello();

解构赋值 (Destructuring Assignment)

允许按照一定模式,从数组和对象中提取值,对变量进行赋值。

// 数组解构
const [x, y] = [1, 2];
console.log(x, y); // 1 2

// 对象解构
const user = { id: 1, name: "John", age: 30 };
const { name, age } = user;
console.log(name, age); // John 30

// 参数解构与默认值
function printUser({ name, age = 18 }) {
    console.log(`User: ${name}, Age: ${age}`);
}
printUser({ name: "Tom" }); // User: Tom, Age: 18

模板字符串 (Template Literals)

使用反引号 `` 定义,支持多行字符串和内嵌变量。

const name = "World";
const greeting = `Hello, 
${name}!`;
console.log(greeting);

展开语法 (Spread Syntax) ...

用于数组合并、对象复制等。

// 数组合并
const arr1 = [1, 2];
const arr2 = [...arr1, 3, 4]; // [1, 2, 3, 4]

// 对象合并/浅拷贝
const obj1 = { a: 1 };
const obj2 = { ...obj1, b: 2 }; // { a: 1, b: 2 }

Set 和 Map 数据结构

Set

类似于数组,但成员的值都是唯一的,没有重复的值。

const s = new Set([1, 2, 3, 4, 4]);
console.log([...s]); // [1, 2, 3, 4] (去重)

s.add(5);
s.has(1); // true
s.delete(2);

Map

类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。

const m = new Map();
const o = {p: 'Hello World'};

m.set(o, 'content');
console.log(m.get(o)); // "content"

m.has(o); // true
m.delete(o);

WeakSet 和 WeakMap

  • WeakSet: 成员只能是对象,且是弱引用(不计入垃圾回收机制)。
  • WeakMap: 键必须是对象,键名是弱引用。常用于深拷贝解决循环引用、DOM 节点元数据存储。

剩余参数 (Rest Parameters)

用于获取函数的多余参数,替代 arguments 对象。

function sum(...numbers) {
    return numbers.reduce((prev, curr) => prev + curr, 0);
}
console.log(sum(1, 2, 3)); // 6

模块化 (Modules)

使用 importexport 进行模块化开发。

// math.js
export const add = (a, b) => a + b;
export default function multiply(a, b) {
    return a * b;
}

// main.js
import multiply, { add } from './math.js';
console.log(add(1, 2));
console.log(multiply(3, 4));

可选链 (Optional Chaining) ?.

安全地访问嵌套对象的属性。

const user = { address: { street: "Main St" } };
console.log(user?.address?.street); // Main St
console.log(user?.contact?.phone); // undefined (不会报错)

空值合并运算符 (Nullish Coalescing) ??

只有当左侧为 nullundefined 时,才返回右侧的值。

const count = 0;
const num = count || 10; // 10 (因为 0 是 falsy)
const num2 = count ?? 10; // 0 (只有 null/undefined 才会取默认值)

Proxy 和 Reflect (元编程)

Proxy

用于修改某些操作的默认行为,等同于在语言层面做出修改,属于一种“元编程”(meta programming)。

const handler = {
    get: function(target, propKey, receiver) {
        console.log(`Getting ${propKey}!`);
        return Reflect.get(target, propKey, receiver);
    },
    set: function(target, propKey, value, receiver) {
        console.log(`Setting ${propKey}!`);
        return Reflect.set(target, propKey, value, receiver);
    }
};

const obj = new Proxy({}, handler);
obj.count = 1; // Setting count!
++obj.count;   // Getting count! -> Setting count!

Reflect

Object 对象的一些明显属于语言内部的方法(如 Object.defineProperty),放到 Reflect 对象上。与 Proxy handler 的方法一一对应。

上次编辑于:
贡献者: 15327360835
Loading...