我只是旧文章的搬运工。🤒
https://github.com/lixinliang/es6-programme-style
文章太长了,就直接提上来了。
Map
,Set
,Proxy
,Reflect
,Decorator
等等,才会出现更优秀的库或者框架,成为新时代的主流技术工具。这是一遍关于 ECMAScript 6
(以下简称 ES6)编程风格的文章。
如果你还没有了解 ES6,可以从这里开始《ECMAScript 6 入门》。
代码规范
众所周知,良好的代码规范
会带来方方面面的好处。
但是,本篇文章不会重复讨论诸如大括号的圣战或者缩进圣战这类的问题。
如果,你想了解更多代码规范
的内容,可以阅读这里 JavaScript 编码规范。
编程风格
编程风格
是什么?编程风格
可以说是代码规范
的子集,我们不会考虑变量命名等问题。
并且,在约束
的程度上,以建议使用
为主。
在一定程度上,与各个团队的代码规范
形成互补,补充关于 ES6 的内容。
快速入门
并不是所有的浏览器能执行 ES6 的代码,但我们可以使用 Babel Compiler 进行代码转译。 或者,你可以直接使用 LegoFlow 马上体验。
星号
带星号的特性,并不是 ES6 的标准特性,它或许仅仅是 ES7 的一个提案,但至少 Babel
已经支持转译了,我们可以尝试使用它们,享受它们带来的便利。
在阅读以下内容前,请谨记以下约定:
webkit
与 trident
。let
替换 var
// 😁
for (let i = 0; i < 3; i++) {
setTimeout(function () {
console.log(i);
}, 100);
}
let
不再具备 var
的变量提升
// 😭
function test () {
flag = true;
// 其他代码
let flag;
if (flag) {
// 预期执行的代码
}
}
复杂类型
作为常量时,它的属性是可以更改的// 😭
const obj = {
value : true
};
obj.value = false;
if (obj.value) {
// 预期执行的代码
}
console.log(obj);
// 😁
let { uid, username, avator } = data;
console.log(uid, username, avator);
// 😁
let param = 'key=value';
let [key, value] = param.split('=');
// ❌
对象不支持“isArray”属性或方法
// 😁
let min = 1;
let max = 0;
if (min > max) {
[min, max] = [max, min];
}
// 😭
let {
uid,
username,
message : [
message0,
message1,
],
} = data;
`
替换'
和"
条件语句
和循环语句
,但可以使用三目运算符
和函数
// 😁
let text = `
name : ${ username }
sex : ${ sex ? 'female' : 'male' }
medal : ${ getMedal() }
`;
标签模板
也是函数
,在 i18n
或者 helper
情景下使用比较适合// 😁
function parse ( templates, ...params ) {
let output = templates[0];
let length = params.length;
if (navigator.language == 'zh-CN') {
// 显示中文内容
for (let index = 0; index < length; index++) {
output += params[index].zh + templates[index + 1];
}
} else {
// 显示英文内容
for (let index = 0; index < length; index++) {
output += params[index].en + templates[index + 1];
}
}
return output;
}
let text = parse`uid : ${ uid }, name : ${ username }, avator : ${ avator }`;
// ❌
对象不支持“freeze”属性或方法
Math.pow
的语法糖// 😁
let hundred = 10 ** 2;
name = name || ''
更优雅与直观,并且更严谨// 😁
function setName ( name = '' ) {
window.name = name;
}
arguments
更灵活// 😁
function foo ( elem, ...params ) {
// ...
console.log(params);
}
函数
时,使用扩展运算符
可以将一个数组
,变为参数序列
// 😁
console.log(...[1, 2, 3], ...document.scripts);
// ❌
对象不支持“isArray”属性或方法
function
关键字的词频,提高编码效率this
与 arguments
关键字,由定义时的环境决定而不是调用的环境setTimeout
的 this
指向 window
而定义各种 self
,_this
,that
// 😁
let image = new Image;
image.onload = function () {
setTimeout(() => {
// 指向 image 而不是 window
console.log(this);
},3000);
};
image.src = url;
this
的情况下,不使用箭头函数
// 😭
function main () {
document.addEventListener('click', ( event ) => {
// 预期是 document 而不是 window
console.log(this);
}, false);
}
main();
链式调用
的方式调用函数
babel
需要开启 Experimental
才能支持// 😁
function set ( key, value ) {
this[key] = value;
return this;
}
console.log({}::set('uid', '123')::set('username', 'Max'));
变量
与属性名
同名时,推荐简写合并,比如调用 ajax
时的传参,保持变量
一致,提高代码可读性// 😁
let username = 'Max';
// 其他代码
let data = {
username,
avator,
};
属性名
支持表达式// 😁
let id = 1024;
let obj = {
['prefix' + id] : id,
};
function
关键字的词频,提高编码效率// 😁
let obj = {
log ( ...args ) {
console.log(...args);
},
};
对象
的可遍历属性拷贝到其他对象
,Object.assign
的语法糖// 😁
let animal = { foot : 4 };
let cat = { ...animal, tail : 1 };
Generator
依赖 regeneratorRuntime
,所以 babel
需要添加 babel-plugin-transform-runtime
插件// 😁
function* Genertor ( arg ) {
// 同步代码,异步执行
let input = yield arg;
console.log(input);
return 'end';
}
let genertor = Genertor('begin');
console.log(genertor.next().value);
console.log(genertor.next('input').value); // 外部注值
// ❌
缺少标识符、字符串或数字
Generator
的语法糖regeneratorRuntime
,所以 babel
需要添加 babel-plugin-transform-runtime
插件// 😁
import $ from 'jquery';
let getData = async ( url ) => {
let data = await $.ajax(url);
return data;
};
getData('http://legox.yy.com/mock/api/33').then(( data ) => {
console.log(data);
});
// ❌
缺少标识符、字符串或数字
构造函数更规范
,可读性更高// 😁
class Widget {
constructor ( ...args ) {
// ...
}
method () {
// 方法
}
static foo () {
// 类的静态方法
}
}
class Pendant extends Widget {
constructor ( ...args ) {
super(...args);
// 继承
}
}
let pendant = new Pendant();
// ❌
对象不支持此操作
babel
需要开启 Experimental
才能支持// 😁
function readonly ( target, name, descriptor ){
descriptor.writable = false;
return descriptor;
}
class Person {
@readonly
name () {
// ...
}
}
// ❌
对象不支持此操作
import
,export
// 😁
import $ from 'jquery';
export default {
// ...
};
import
将会 提升
到模块的头部// 😭
window.jQuery = require('$');
import 'jquery.parallax';