Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

项目&代码风格指南 #41

Open
evantianx opened this issue May 26, 2017 · 7 comments
Open

项目&代码风格指南 #41

evantianx opened this issue May 26, 2017 · 7 comments

Comments

@evantianx
Copy link
Owner

evantianx commented May 26, 2017

对象

  • 创建对象时多用对象字面量,不用new操作符创建

    const item = new Object();   
    
    const item = {}; ⭕️
  • 对象中有计算属性时,直接用计算属性:

    function getKey(k) {
      return `a key named ${k}`
    }
    
    const obj = {
      id: 5,
      name: 'Jack',
    }
    obj[getKey('enabled')] = true   
    
    const obj = {
      id: 5,
      name: 'Jack',
      [getKey('enabled')]: true,   ⭕️
    }                                               
  • 使用对象方法简写,属性简写

    const name = 'Jack'
    const atom = {
       name: name,                  
       sayname: function() {   
         return this.name
       }
    }
    
    const atom = {
      name,   ⭕️
      sayname() {    ⭕️
        return this.name
      }
    }

    同时为了保持代码整洁性和易读性,建议将简写属性全部集中于对象开头处。

  • 在不必要的情况下,不要为对象的属性名添加引号

    const item = {   
      'foo': 3,
      'bar': 4,
      'foo-bar': 5, 
    }
    
    const item = {   ⭕️
      foo: 3,
      bar: 4,
      'foo-bar': 5, 
    }
  • 不要直接调用Object.prototype中的方法如hasOwnProperty,propertyIsEnumerableisPrototypeOf

    因为这些属性很容易被覆盖

    console.log(object.hasOwnProperty(key))     
    
    console.log(Object.prototype.hasOwnProperty.call(object, key))  ⭕️ 
    
    const has = Object.prototype.hasOwnProperty  ❤️   //cache it!
  • 通过对象展开符而不是Object.assign来进行浅复制,同时这样也可以显示忽略某些属性来复制其他属性。

    const original = { a: 1, b: 2 }   
    const copy = Object.assign(original, { c: 3 })   ⚠️  
    delete copy.a  
    console.log(original.a) // undefined
    
    const original = { a: 1, b: 2 }   
    const copy = Object.assign({}, original, { c: 3 })     
    delete copy.a 
    console.log(original.a) // 1
    
    const original = { a: 1, b: 2 }   
    const copy = { ...original, c: 3 }    ⭕️ 
    delete copy.a  
    console.log(original.a) // 1
    
    const { a, ...noA } = copy   // noA => { b: 2, c: 3 } 

    Object.assign MDN

@evantianx
Copy link
Owner Author

evantianx commented Jun 2, 2017

数组

  • 使用字面量来创建数组

    const items = new Array()    
    const items = []    ⭕️
  • 使用Array.push来为数组添加成员

    const  someStack = []
    
    someStack[someStack.length] = 'something'     
    
    someStack.push('something')   ⭕️  
  • 使用扩展操作符来复制数组

    const len = items.length
    const itemCopy = []
    
    for (let i = 0; i < len; i++) {      
      itemCopy[i] = items[i]         
    }
    
    const itemsCopy = [...items]   ⭕️   
  • Array.from来转换类数组为数组

    const foo = document.querySelectorAll('.foo')
    const nodes = Array.from(foo)
  • 总是在数组方法回调函数中返回语句

@evantianx
Copy link
Owner Author

evantianx commented Jun 2, 2017

解构赋值

  • 当接收及使用某个对象的多个属性值时,使用对象解构赋值

    function getFullName(user) {
      const firstName = user.firstName       
      const lastName = user.lastName   
      
      return `${firstName} ${lastName}`
    }
    
    function getFullName(user) {
      const { firstName, lastName } = user    ⭕️ 
      return `${firstName} ${lastName}`
    }
    
    function getFullName({ firstName, lastName }) {     ❤️ 
      return `${firstName} ${lastName}`
    }
  • 调用数组成员时,推荐使用解构赋值

    const arr = [1, 2, 3, 4]
    
    const first = arr[1]        
    const second = arr[2]
    
    const [first, second] = arr    ⭕️ 
  • 函数有多个返回值时使用对象解构赋值而非数组解构赋值

    因为在之后调用时,使用数组结构赋值的结果要考虑顺序,而对象结构赋值不需要

    function processInput(input) {
      // something happens
      return [top, right, bottom, left]
    }
    const [top, _, bottom] = processInput(input)  // 需要考虑顺序   ❌
    
    function processInput(input) {
      // something happens
      return { top, right, bottom, left }
    }
    const { top, bottom } = processInput(input)  // 无需考虑顺序  ⭕️ 

@evantianx
Copy link
Owner Author

evantianx commented Jun 2, 2017

函数

  • 使用命名函数表达式而非函数声明

    函数声明会造成调用混乱,匿名函数表达式会使得 Debug 非常困难.

    关于命名函数表达式的讨论

    function foo() {       
      // ...
    }
    
    const foo = function () {      
      // ...
    }
    
    const foo = function bar() {    ⭕️ 
      //...
    }
  • 不要使用 arguements 来调用函数参数, 用...代替

    function concatenateAll() {
      const args = Array.prototypr.slice.call(arguments)     
      return args.join('')
    }
    
    function concatenateAll(...args) {      ⭕️ 
      return args.join('')
    }
  • 使用默认参数表达式

    function handleThings(opts) {      ⚠️ 
      // 非常不推荐,这样会改变参数值,
      // 同时如果 opts 为假值则会将其设置为一个对象
      opts = opts || {}
      // ...
    }
    
    function handleThings(opts) {       
      if (opts === void 0) {
        opts = {}
      }
    }
    
    function handleThings(opts = {}) {    ⭕️ 
      // ...
    }
  • 把带有默认参数的参数统一放在最后

  • 函数中的空格

    const x = function () {}     ⭕️ 
    const y = function a() {}    ⭕️ 
  • 永远不要修改或者重新赋值给传入的参数

@evantianx
Copy link
Owner Author

evantianx commented Jun 2, 2017

  • 总是用类来构建对象原型

    function Queue(contents = []) {       
      this.queue = [...contents]
    }
    Queue.prototype.pop = function () {
      const value = this.queue[0]
      this.queue.splice(0, 1)
      return value
    }
    
    class Queue {            ⭕️ 
      constructor(contents = []) {
        this.queue = [...contents]
      }
      pop() {
        const value = this.queue[0]
        this.queue.splice(0, 1)
        return value
      }
    }     
  • extends 来实现继承

    class PeekableQueue extends Queue {
      peek() {
        return this.queue[0]
      }
    }
  • 类如果不存在 constructor 会调用默认 constructor,所以不需要创建空的 constructor

@evantianx
Copy link
Owner Author

evantianx commented Jun 2, 2017

Modules

  • 不要在 import 中同时进行 export

    export { es6 as default } from './AirbnbStyleGuide'         
    
    import { es6 } from './AirbnbStyleGuide'           ⭕️ 
    export default es6
  • 同一路径只引入一次

  • 若某个模块仅有一个输出, 则使用默认输出

    export function foo() {}         
    
    export default function foo() {}       ⭕️ 
  • 将所有import写在非import语句的前面

    因为import都是声明提升的, 这样写不易出现错误

@evantianx evantianx changed the title <Airbnb JavaScript Style Guide>小记 项目&代码风格指南 Jul 8, 2017
@evantianx
Copy link
Owner Author

项目风格指南

@liuchong
Copy link

liuchong commented Oct 21, 2017

const foo = function bar() { ⭕️
//...
}
請問。。。這不多此一舉嗎? function foo () {} 完成的時候,就會創建一個foo變量

我覺得原義應該是
const short = function longDescriptiveFunctionName () {}
這樣可以代碼裏面寫起來簡單,並且函數的名字也比較有描述性

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants