与ES5编程方式相比,用ES6方式编程使代码更加高效、易读和易于维护。本章参考ECMAScript6入门教程 。
1.let取代var
ES6新增两个变量声明方式let
和const
,其中,let可以完全取代var,且不用担心副作用。
1 2 3 4 5 6 7 8 9 10 11 12 if (true ){ let num = 2 ; } for (let i = 0 ; i < 3 ; i++){ console .log(i) } if (true ){ console .log(num2); let num2 = 5 ; }
上述代码的优势体现在两个方面,一、前两个代码块如果使用var替代,由于var存在变量提升的作用,想当于声明了两个全局变量,这并非初衷;二、第三段代码使用var代替,代码并不会报错,而是输出undefined,这违反了变量先声明后使用的原则。
2.const常量和线程安全
在let和const之中,应该优先使用const,尤其是在全局范围内,应该设置常量,不应该设置变量。
1 2 3 4 5 6 7 8 9 10 var a = 1 , b = 2 , c = 3 ;const a = 1 ;const b = 2 ;const c = 3 ;const [a, b, c] = [1 , 2 , 3 ];
使用const有三个好处:一、const提醒阅读代码的人,该声明的量是常量,不可更改;二、使用const声明的量JavaScript解析会内部优化;三、有利于JavaScript后续多线程实现的安全。
3.模板字符串
静态字符串一律使用单引号或反引号,不使用双引号。动态字符串使用反引号。
1 2 const str1 = 'abcde' ;const str2 = `abc + ${val} `
4.结构赋值
使用数组成员对变量进行赋值时,优先使用结构赋值。
1 2 3 4 const arr = [5 , 56 , 68 , 2 ];const [num1 , num2] = arr;console .log(num1); console .log(num2);
函数的参数如果是对象的成员,优先使用结构赋值。
1 2 3 4 5 let obj = {id : 1 , name : 'bob' , age : 32 };function printInfo ({name, age} ) { console .log(name + age); } printInfo(obj);
如果函数返回多个值,优先使用对象的解构赋值,而不是数组的解构赋值。
1 2 3 4 function processInput (input ) { return { left, right, top, bottom }; } const { left, right } = processInput(input);
5.对象
对象定义可以使用简洁表达式,属性名可使用属性表达式。
1 2 3 4 5 6 7 8 9 10 11 12 let name = 'bobo' ;let color = 'red' ;const obj = { name, color }; let lastWord = 'last word' ;const a = { 'first word' : 'hello' , [lastWord]: 'world' }; a['first word' ] a[lastWord] a['last word' ]
单行定义的对象,最后一个成员不以逗号结尾;多行定义的对象,最后一行用逗号结尾。
1 2 3 4 5 6 const obj1 = {id : 1 , attr : 'val' };const obj2 = { id: 2 , name: 'lina' , classroom: 324 , };
对象的定义尽量静态化,如果非要修改或者添加属性,使用Object.assign()
。
1 2 3 4 5 6 const obj = { name: 'bob' , sex: 'man' }; const obj2 = Object .assign({id : 1 , age : 12 }, obj);console .log(obj2.id);
定义对象的方法时,可以使用简单表达法。
1 2 3 4 5 6 7 8 let name = 'bobo' ;const people = { name, age: 65 , sayHi(val){ console .log(val); } };
6.数组
使用扩展运算符...
拷贝数组。
1 2 3 let arr = [1 , 3 , 4 , 9 , 45 ];const copy = [...arr];console .log(copy);
7.函数
当需要使用立即执行函数、函数表达式、简单的回调函数时可以写成箭头函数的形式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 (()=> { let variable = 1 ; })() let fn = () => { let variable = 1 ; } let btn = document .getElementById('btn' );btn.addEventListener('click' , (e )=> { console .log(e.target); });
使用默认值语法设置函数参数的默认值。
1 2 3 function (param1 = 0 , param2 = {} ) { }
8.Map结构
注意区分 Object 和 Map,只有模拟现实世界的实体对象时,才使用 Object。如果只是需要key: value的数据结构,使用 Map 结构。因为 Map 有内建的遍历机制。
1 2 3 4 5 6 7 8 9 10 let arr = [['id' , 34 ], ['price' , 765 ]];let map = new Map (arr);for (let key of map.keys()) { console .log(key); } for (let value of map.values()) { console .log(value); }
9.Class类
用class可以替代ES5中基于构造函数和原型的类的实现,写法简洁便于理解,extends实现类的继承。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class People { constructor (age, name){ this .age = age; this .name = name; } sayHi(){ console .log(`Hello, I am ${this .name} , ${this .age} years old.` ); } } class Student extends People { constructor (age, name, role){ super (age, name); this .role = role; } sayRole(){ console .log(`I am a ${this .role} .` ); } } let xiaoming = new Student(12 , 'xiaoming' , 'Students' );xiaoming.sayHi(); xiaoming.sayRole();
10.模块
JavaScript提供标准的Module语法,以替代之前的require()。
1 2 3 4 5 6 7 8 9 10 11 12 var obj = { attribute: 'value' , fn: function ( ) { console .log(666 ); } }; export default obj;import {attribute, fn} from 'module' ;fn();