ES6+新特性详解 JavaScript作为前端开发的核心语言,在不断演进和发展。ES6(ECMAScript 2015)标志着JavaScript的重大飞跃,引入了许多革命性的特性。后续的ES7、ES8、ES9等版本也在持续扩展JavaScript的能力。
在本文中,我将深入讲解ES6+的重要新特性,从基础语法到高级特性,帮助你掌握现代JavaScript的核心概念,提升开发效率。
1. ES6核心语法特性 1.1 let和const声明 function testLet ( ) { let x = 1 ; if (true ) { let x = 2 ; console .log (x); } console .log (x); } const PI = 3.14159 ;const obj = { name : 'John' };obj.name = 'Jane' ; { console .log (typeof x); let x = 10 ; }
1.2 箭头函数 const add = (a, b ) => a + b;console .log (add (2 , 3 )); const sayHello = ( ) => 'Hello' ;console .log (sayHello ()); const double = x => x * 2 ;console .log (double (5 )); const multiply = (a, b ) => { const result = a * b; console .log (`计算结果: ${result} ` ); return result; }; function Person ( ) { this .age = 0 ; setTimeout (() => { this .age = 25 ; console .log (this .age ); }, 1000 ); } const p = new Person ();
1.3 模板字符串 const name = 'John' ;const age = 30 ;const message = `Hello, my name is ${name} and I'm ${age} years old.` ;console .log (message); const html = ` <div class="card"> <h1>${name} </h1> <p>${age} years old</p> </div> ` ;const a = 5 ;const b = 10 ;const mathExpression = `a + b = ${a + b} ` ;console .log (mathExpression); const formatDate = (date ) => date.toLocaleDateString ();const dateInfo = `今天是 ${formatDate(new Date ())} ` ;
1.4 解构赋值 const numbers = [1 , 2 , 3 , 4 , 5 ];const [first, second, ...rest] = numbers;console .log (first); console .log (second); console .log (rest); const person = { name : 'John' , age : 30 , city : 'New York' , country : 'USA' }; const { name, age, ...otherProps } = person;console .log (name); console .log (age); console .log (otherProps); const config = { host : 'localhost' , port : 3000 , timeout : 5000 }; const { host, port = 8080 , timeout = 10000 } = config;console .log (port); const { name : userName } = person;console .log (userName); const user = { id : 1 , profile : { name : 'John' , address : { city : 'New York' , zip : '10001' } } }; const { profile : { address : { city } } } = user;console .log (city);
1.5 扩展运算符 const arr1 = [1 , 2 , 3 ];const arr2 = [4 , 5 , 6 ];const combined = [...arr1, ...arr2];console .log (combined); const obj1 = { a : 1 , b : 2 };const obj2 = { c : 3 , d : 4 };const merged = { ...obj1, ...obj2 };console .log (merged); function sum (...numbers ) { return numbers.reduce ((acc, num ) => acc + num, 0 ); } console .log (sum (1 , 2 , 3 , 4 )); const chars = [...'hello' ];console .log (chars);
2. ES6+数据结构与对象 2.1 Map和Set const userMap = new Map ();userMap.set ('name' , 'John' ); userMap.set ('age' , 30 ); userMap.set ('skills' , ['JavaScript' , 'React' , 'Node.js' ]); console .log (userMap.get ('name' )); console .log (userMap.has ('age' )); console .log (userMap.size ); for (const [key, value] of userMap) { console .log (`${key} : ${value} ` ); } const skills = new Set (['JavaScript' , 'React' , 'Node.js' , 'JavaScript' ]);console .log (skills.size ); skills.add ('Python' ); skills.delete ('React' ); console .log (skills.has ('Node.js' )); const setA = new Set ([1 , 2 , 3 ]);const setB = new Set ([3 , 4 , 5 ]);const union = new Set ([...setA, ...setB]);console .log (union); const intersection = new Set ([...setA].filter (x => setB.has (x)));console .log (intersection); const difference = new Set ([...setA].filter (x => !setB.has (x)));console .log (difference);
2.2 WeakMap和WeakSet const weakMap = new WeakMap ();const user = { name : 'John' };weakMap.set (user, 'John Doe' ); console .log (weakMap.get (user)); const weakSet = new WeakSet ();const obj1 = { id : 1 };const obj2 = { id : 2 };weakSet.add (obj1); console .log (weakSet.has (obj1)); console .log (weakSet.has (obj2));
2.3 Object扩展 const target = { a : 1 , b : 2 };const source1 = { b : 3 , c : 4 };const source2 = { d : 5 };const result = Object .assign (target, source1, source2);console .log (result); console .log (target === result); console .log (Object .is (5 , 5 )); console .log (Object .is (NaN , NaN )); console .log (Object .is (+0 , -0 )); const person = { name : 'John' , age : 30 , city : 'New York' }; console .log (Object .keys (person)); console .log (Object .values (person)); console .log (Object .entries (person)); const obj1 = { a : 1 , b : 2 };const obj2 = { ...obj1, c : 3 };console .log (obj2);
2.4 Symbol const id = Symbol ('id' );const user = { [id]: 123 , name : 'John' , age : 30 }; console .log (user[id]); console .log (user.name ); console .log (Symbol ('id' ) === Symbol ('id' )); const globalSymbol = Symbol .for ('global' );const sameSymbol = Symbol .for ('global' );console .log (globalSymbol === sameSymbol); console .log (Symbol .keyFor (globalSymbol)); console .log (Symbol .iterator ); console .log (Symbol .toStringTag );
3. ES6+函数特性 3.1 默认参数 function greet (name = 'Guest' , greeting = 'Hello' ) { return `${greeting} , ${name} !` ; } console .log (greet ()); console .log (greet ('John' )); console .log (greet ('Jane' , 'Hi' )); function multiply (a, b = a * 2 ) { return a * b; } console .log (multiply (5 )); console .log (multiply (2 , 3 )); function createUser ({ name = 'Guest' , age = 18 } = {} ) { return { name, age }; } console .log (createUser ()); console .log (createUser ({ name : 'John' }));
3.2 剩余参数 function sum (...numbers ) { return numbers.reduce ((acc, num ) => acc + num, 0 ); } console .log (sum (1 , 2 , 3 , 4 , 5 )); function processInput (action, ...data ) { console .log (`Action: ${action} ` ); console .log ('Data:' , data); return data.map (item => `${action} -${item} ` ); } const result = processInput ('double' , 1 , 2 , 3 );console .log (result);
3.3 生成器函数 function * numberGenerator ( ) { yield 1 ; yield 2 ; yield 3 ; } const generator = numberGenerator ();console .log (generator.next ()); console .log (generator.next ()); console .log (generator.next ()); console .log (generator.next ()); function * countUpTo (max ) { let count = 0 ; while (count < max) { yield count; count++; } } const counter = countUpTo (3 );console .log (counter.next ().value ); console .log (counter.next ().value ); console .log (counter.next ().value ); function * fibonacci ( ) { let a = 0 , b = 1 ; while (true ) { yield a; [a, b] = [b, a + b]; } } const fib = fibonacci ();for (let i = 0 ; i < 10 ; i++) { console .log (fib.next ().value ); }
4. ES7+新特性 4.1 Array.includes() const numbers = [1 , 2 , 3 , 4 , 5 ];console .log (numbers.includes (3 )); console .log (numbers.includes (6 )); console .log (numbers.includes (3 , 1 )); console .log (numbers.includes (1 , 2 ));
4.2 指数运算符 const square = 2 ** 2 ; const cube = 2 ** 3 ; const power = 2 ** 10 ; const result = 2 ** 3 ** 2 ; let num = 5 ;num **= 2 ;
4.3 Object.values()和Object.entries() const person = { name : 'John' , age : 30 , city : 'New York' }; const values = Object .values (person);console .log (values); const entries = Object .entries (person);console .log (entries); const userMap = new Map (entries);console .log (userMap.get ('name' ));
5. ES8+异步编程 5.1 异步函数(Async/Await) async function fetchUserData (userId ) { try { const response = await fetch (`/api/users/${userId} ` ); const user = await response.json (); return user; } catch (error) { console .error ('Error fetching user:' , error); throw error; } } fetchUserData (1 ) .then (user => console .log (user)) .catch (error => console .error ('Error:' , error)); async function fetchMultipleUsers (userIds ) { try { const promises = userIds.map (id => fetchUserData (id)); const users = await Promise .all (promises); return users; } catch (error) { console .error ('Error fetching users:' , error); throw error; } } async function fetchUsersWithIndependentErrors (userIds ) { const results = await Promise .allSettled ( userIds.map (id => fetchUserData (id)) ); return results.map (result => result.status === 'fulfilled' ? { success : true , data : result.value } : { success : false , error : result.reason } ); }
5.2 Object.values()和Object.entries() const user = { name : 'John' , age : 30 , city : 'New York' }; const userMap = new Map (Object .entries (user));console .log (userMap); Object .entries (user).forEach (([key, value] ) => { console .log (`${key} : ${value} ` ); }); const userArray = Object .entries (user).map (([key, value] ) => ({ [key]: value })); console .log (userArray);
5.3 String.trimStart()和String.trimEnd() const text = ' Hello World ' ;console .log (text.trimStart ()); console .log (text.trimEnd ()); console .log (text.trim ()); function cleanInput (input ) { return input.trimStart ().trimEnd (); } const userInput = ' John Doe ' ;const cleanName = cleanInput (userInput);console .log (cleanName);
6. ES9+高级特性 6.1 异步迭代器 async function * asyncCounter (max ) { let count = 0 ; while (count < max) { await new Promise (resolve => setTimeout (resolve, 1000 )); yield count++; } } async function runAsyncCounter ( ) { const counter = asyncCounter (3 ); for await (const value of counter) { console .log (`Count: ${value} ` ); } } const asyncIterable = { [Symbol .asyncIterator ]() { let count = 0 ; return { next ( ) { return new Promise (resolve => { setTimeout (() => { if (count < 3 ) { resolve ({ value : count++, done : false }); } else { resolve ({ value : undefined , done : true }); } }, 1000 ); }); } }; } }; async function consumeAsyncIterable ( ) { for await (const value of asyncIterable) { console .log (value); } }
6.2 Promise.finally() function fetchWithCleanup (url ) { return fetch (url) .then (response => response.json ()) .catch (error => { console .error ('Error:' , error); throw error; }) .finally (() => { console .log ('Cleanup completed' ); }); } function databaseOperation ( ) { const connection = createDatabaseConnection (); return connection.query ('SELECT * FROM users' ) .then (results => { return results; }) .catch (error => { throw error; }) .finally (() => { connection.close (); }); }
6.3 Rest/Spread属性 const user = { id : 1 , name : 'John' , age : 30 , email : 'john@example.com' , phone : '123-456-7890' }; const { id, name, ...userInfo } = user;console .log (id); console .log (name); console .log (userInfo); const defaults = { theme : 'light' , language : 'en' , notifications : true }; const userSettings = { ...defaults, theme : 'dark' , fontSize : 16 }; console .log (userSettings);
7. ES10+最新特性 7.1 Array.flat()和Array.flatMap() const nestedArray = [1 , [2 , 3 ], [4 , [5 , 6 ]]];const flatArray = nestedArray.flat ();console .log (flatArray); const deeplyNested = [1 , [2 , [3 , [4 , [5 ]]]]];const deeplyFlat = deeplyNested.flat (3 );console .log (deeplyFlat); const words = ['Hello' , 'World' ];const letters = words.flatMap (word => word.split ('' ));console .log (letters);
7.2 可选链操作符 const user = { name : 'John' , address : { street : '123 Main St' , city : 'New York' } }; const city = user && user.address && user.address .city ;console .log (city); const cityWithOptional = user?.address ?.city ;console .log (cityWithOptional); const getUserName = (user ) => user?.profile ?.getName ();console .log (getUserName (user));
7.3 空值合并操作符 const name = null ?? 'Guest' ;console .log (name); const age = undefined ?? 18 ;console .log (age); const defaultValue = 'default' ;const value = null ?? defaultValue;console .log (value); const result1 = false ?? 'fallback' ; const result2 = false || 'fallback' ; const result3 = 0 ?? 'fallback' ; const result4 = 0 || 'fallback' ; const result5 = '' ?? 'fallback' ; const result6 = '' || 'fallback' ;
8. 实际应用场景 8.1 数据转换和映射 const users = [ { id : 1 , name : 'John' }, { id : 2 , name : 'Jane' }, { id : 3 , name : 'Bob' } ]; const userMap = new Map (users.map (user => [user.id , user]));console .log (userMap.get (2 )); const updateUser = (user, updates ) => { const { id, ...rest } = user; return { id, ...rest, ...updates }; }; const updatedUser = updateUser (users[0 ], { name : 'Johnny' });console .log (updatedUser);
8.2 异步数据处理 async function fetchUserWithPosts (userId ) { try { const [user, posts] = await Promise .all ([ fetch (`/api/users/${userId} ` ), fetch (`/api/users/${userId} /posts` ) ]); const userData = await user.json (); const postsData = await posts.json (); return { ...userData, posts : postsData }; } catch (error) { console .error ('Error:' , error); throw error; } } async function fetchMultipleUsers (userIds ) { const userPromises = userIds.map (id => fetchUserWithPosts (id)); return Promise .allSettled (userPromises); }
8.3 函数式编程实践 const users = [ { id : 1 , name : 'John' , age : 30 }, { id : 2 , name : 'Jane' , age : 25 }, { id : 3 , name : 'Bob' , age : 35 } ]; const adultUsers = users .filter (user => user.age >= 30 ) .map (user => ({ id : user.id , name : user.name })); const stats = users.reduce ((acc, user ) => { acc[user.age ] = (acc[user.age ] || 0 ) + 1 ; return acc; }, {}); const initialState = { users : [], loading : false , error : null }; const fetchUsersSuccess = (state, users ) => ({ ...state, users, loading : false }); const fetchUsersError = (state, error ) => ({ ...state, error, loading : false });
9. 性能优化建议 9.1 使用const和let const PI = 3.14159 ;const API_BASE_URL = 'https://api.example.com' ;let counter = 0 ;function increment ( ) { counter++; } var oldWay = 'This is old' ;console .log (oldWay); const user = { name : 'John' };let isLoggedIn = false ;
9.2 解构赋值优化 function processUser ({ id, name, email, ...profile } ) { console .log (`Processing user: ${name} (${email} )` ); return { id, ...profile }; } function createConfig ({ endpoint = 'https://api.example.com' , timeout = 5000 , retries = 3 } = {} ) { return { endpoint, timeout, retries }; } const config = createConfig ({ timeout : 3000 , retries : 5 });
9.3 数组方法优化 const numbers = [1 , 2 , 3 , 4 , 5 ];const doubled = numbers.map (n => n * 2 );const evens = numbers.filter (n => n % 2 === 0 );const sum = numbers.reduce ((acc, n ) => acc + n, 0 );const hasEven = numbers.some (n => n % 2 === 0 );const allPositive = numbers.every (n => n > 0 );
10. 总结 ES6+为JavaScript带来了许多强大的新特性,极大地提升了开发效率和代码质量。从基础语法特性到高级异步编程,这些新特性让我们能够写出更加简洁、优雅的代码。
在实际开发中,我们需要根据项目需求和浏览器支持情况选择合适的新特性。同时,也要注意性能优化和代码可维护性,确保代码能够长期维护。
希望本文能够帮助你更好地理解和使用ES6+的新特性。如果你有任何问题或建议,欢迎在评论区交流分享!
本文由笔者根据实际项目经验总结,如有疏漏之处,敬请指正。