Giter Club home page Giter Club logo

es6-code-style's People

Stargazers

 avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

es6-code-style's Issues

spread

数组展开

不要拿这个做数组的复制:

let myArray = [...oldArray]; // 别这样

这个东西在babel编译过来有一些小BUG,babel会默认编译成[].concat(oldArray),但其实应该用iterator来做的

数组复制还是建议用Array.from来做

iterator

迭代器

回头看看你的代码,也许不少地方原来判断是否数组的,现在可以改成判断是否迭代器了

正确的判断方法:

function isIterable(obj) {
    return obj && typeof obj[Symbol.iterator] === 'function';
}

注意MapSetlength属性但值不是你想要的,所以乖乖用迭代来做

for .. of

对于数组,如果我的逻辑只有一个语句,可以使用forEach加箭头函数,看着清新

如果逻辑有多个语句,建议使用for .. of换行缩进都舒服

如果你需要continue;break;那用for .. of没跑了

如果你只遍历数组,且需要i的话用for就行了

现在的for .. of没有浏览器优化,速度和forEach差不多,所以你特别想要性能请回到for循环

Anyway,for .. in不是你想要的,正确的遍历对象的姿势:

for (let key of Object.keys(obj)) {
    // key, obj[key]
}

在未来会有let [key, value] of obj的但现在没有- -

destructuring

解构

不要用来一次定义多个变量,请乖乖一个一个定义

不要一次解构太多的东西,比如一个对象10个key你要解构出来,只能共产党保佑你一行120字符够用了

不要做2层以上的解构,大部分人会看蒙的

剩下的,待讨论,我觉得你能hold住就用吧

module

导出

export语句并不影响后面的语句的类型,即:

export default class Foo {
}

虽然有export在前面,但后面还是认为是一个类定义,所以最后不加分号

默认导出和命名导出

如果导出的东西并不相关,且往往使用者只会选择其中非常有限的几个(如5个以内),建议使用命名导出

如果导出的东西较多都会被用上(比如util对象),或者他们之间有相关性,建议默认导出一整个对象

导入

因为import会被提升到当前模块的作用域,所以不得在其它作用域中写import语句,即我们不能在方法、函数、eval等地方写,再简单些说,import前应该没有缩进

建议import全部写在最前面,类似Java的写法,这和var不一样,import是一个模块的依赖元数据

导入语法按照可行性依次作如下选择:

  1. import 'xxx'; 只要导入,不用
  2. `import xxx from 'xxx;' 导入默认的
  3. `import {xxx} from 'xxx;' 导入命名的
  4. import {xxx as yyy, default as zzz} from xxx; 导入后还要自己命名

async functions

统一使用规则,在一个项目/包中,要么全用,要么全不用,混用只会让理解更难

如果选择全用,那么:

  1. 基本不会出现then的调用,都是await,特殊情况看后文
  2. 基本不会出现catch的调用,都是try/catch,特殊情况看后文
  3. 所有返回或使用Promise的函数统一标上async,此时jsdoc上的@return可以直接写resolve后的类型,这样把异步函数难写jsdoc的问题也解决了
  4. 不要写return await xxx();,没任何意义,await只在函数流程的中间用,表示不要立刻执行下一行代码,而return是最后一行了
  5. 不可避免地还是会要用到new Promise的形式,比如把一些事件转成Promise,所以不要认为async可以让你看不到Promise

特殊情况:

  1. 你需要返回一个非标准的Promise,比如一个带有abort()方法的XHR对象,那么你不能使用async函数
  2. 你要对一个Promise做后续逻辑处理但是返回的依旧是这个Promise本身而不是then衍生出来的新的Promise,那么就要用到thencatch

decorators

这是ES7的Stage 1提案,用不用自己选择

属性装饰

不要对属性用装饰,因为descriptor.initializer的提案属于一个非常不稳定的状态,虽然decorator是Stage 1的,但是其中的属性装饰正是讨论的重点

方法装饰

建议使用,记住装饰是不能继承的,要小心这个坑

装饰也能用在类上,相当于对构造函数使用

装饰逻辑执行的时候,不能使用target上的任何属性,需要注意

对象属性装饰

装饰同样可在对象上使用,但不建议用,也很少有这样的场景

function argument & parameter

默认值

能用就用

当默认值不变的时,建议用一个常量保存,避免每次创建的开销

剩余参数

建议用来代替arugments

function add(...items) {
    myArray.push(...items);
    // 不用写myArray.push.apply(myArray, arguments);
}

同时super()的调用不能用arguments,只能用剩余参数

arrow functions

函数语法选择

箭头函数的特点是:

  1. 语法简单
  2. 固定this
  3. babel编译后性能会较低(因为固定this)

建议如下:

  1. 在模块作用域(顶级作用域)的函数都使用function foo() {},不要用箭头函数,这里用不了this
  2. 如果需要变thisthis不是当前词法this的,使用function foo() {},典型的就是声明一个property descriptor里的getsetthis是依赖执行时给定的。不过尽量避免变this的函数出现
  3. 需要递归的用function foo() {},别蛋疼用去Y因子做这事,你不累看的人累
  4. 对象直接量和类里面能用方法语法就用
  5. 其它情况能用箭头就用箭头
  6. 需要绑定词法this的一概用箭头,甚至可以不用bind

箭头函数

参数一定要用括号,哪怕只有一个参数

只有一个语句的函数不换行不写return不加大括号

ajax(url).then((result) => console.log(result));
array.map((item) => item.name);

避免多个箭头函数嵌套,看得眼疼

template string

模板字符串

默认的模板字符串推荐使用,在${}中可以使用变量也可以使用任意的表达式

模板字符串可以多行,但缩进上会比较丑,自已选择

规范检查工具需要对模板字符串的缩进做特殊处理,允许任意的缩进

enhance object literal

成员方法

与类方法同样规则,在可能的情况下使用标准的方法语法,与类不同的是,方法的}后必须有逗号,不然是语法错:

let foo = {
    bar(alice, bob) {
        // code
    },

    prop: 3
}

当你需要一个箭头函数时,可以不使用方法语法

对象解构绑定

当一个对象中所有的key都可以解构绑定时,必须使用解构绑定:

let x = 1;
let y = 2;
let foo = {x, y}; // x和y都能直接绑定

当有任意一个key不能解构绑定时,所有的key不得使用解构绑定:

let x = 1;
let foo = {x: x, y: 2}; // y不能绑定所以x也不能
let bar = {x, y: 2}; // 这个写法是不对的

计算属性

该用就用

class

类声明

正常语法,类声明结尾不加分号,类表达式结果必须加分号,这点和function等同

正常情况下很少写类表达式

成员顺序

class中的成员按如下顺序排列:

  1. 所有属性,类属性是一个Stage 0的提案,用不用看自己高兴
  2. constructor
  3. 所有override的方法
  4. 所有带正常名字的方法
  5. 所有使用Symbol的方法

类属性

如上所说,类属性是一个Stage 0的提案,用不用看自己高兴

类属性经过编译以后会变成在constructor中的赋值语句,因此如果你要把属性定义到prototype上,则不能使用类属性的语法,这个时候比较建议定义个getter去覆盖掉属性,这样在prototype上也能生效

如果你希望使用类属性,又有各种因素(引用相等、性能等)考虑,可以使用一个常量然后类属性值等于这个常量

类属性后面必须以分号结尾:

class Foo {
    foo = 3; // 分号必须
}

这是考虑到代码压缩,如果是这样的代码:

const MY_VALUE = 3;

class Foo {
    foo = MY_VALUE

    bar = 3;
}

如果压缩工具不怎么给力,可能变成:

class Foo {
    foo = MY_VALUEbar = 3
}

显然这是错的

类方法

类方法一概使用正常的方法写法:

class Foo {
    foo(alice, bob) {
        // code
    }
}

方法结尾}不加分号

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.