资讯专栏INFORMATION COLUMN

学习笔记——JavaScript 编码规范

lufficc / 1812人阅读

类型 基本类型
 - string
 - number
 - boolean
 - null
 - undefined
 - symbol(表示独一无二的值,使用时需要注意浏览器是否支持)
     //example
    const symbol1 = Symbol();
    const symbol2 = Symbol(42);
    const symbol3 = Symbol("foo");
    
    console.log(typeof symbol1);
    // expected output: "symbol"
    
    console.log(symbol3.toString());
    // expected output: "Symbol(foo)"
    
    console.log(Symbol("foo") === Symbol("foo"));
    // expected output: false
复杂类型
- array
- object
- function
声明变量
//块级作用域内有效
- let
//块级作用域内有效 不可重复赋值
- const
对象 直接声明
//bad
let obj = new Object();
//good
let obj = {};
动态属性名
//bad
function getKey(key){
    return `${key}`
}
let obj = {
    id:1
    name:"jack"
}  
obj[getKey("age")] = 18;
console.log(obj.age) //18

//good
let obj = {
    name:"jack",
    age:18,
    [getKey("age")]:18
}  
对象方法简写
//bad
let obj = {
    name:"jack",
    age:18,
    show:function(arg){
        console.log(arg)
    }
}  
//good
let obj = {
    name:"jack",
    age:18,
    show(arg){
        console.log(arg)
    }
}  
属性值简写
//bad
let age = 18;
let obj = {
    name:"jack",
    age:age
}
//good
let obj = {   
    age,//简写最好放前面
    name:"jack",
    "data-id":5//键名尽量不加引号,除非没有引号不合法
}
不要直接使用Object.prototype的方法
//不要直接使用Object.prototype的方法,如hasOwnProperty, propertyIsEnumerable和isPrototypeOf
//bad
let obj = {
    id:1,
    name:"jack"
}
obj.hasOwnProperty("name");
//good
Object.prototype.hasOwnProperty.call(obj,"name");
//best
var has = Object.prototype.hasOwnProperty;
has.call(obj,"name")
用变量的解构赋值代替Object.assign()做浅拷贝
//用变量的解构赋值代替Object.assign()做浅拷贝
//bad
let ori = {a:1,b:2};
let copy = Object.assign({},ori,{c:3});
//good
let ori = {a:1,b:2};
let copy = {...ori,c:3};//{a:1,b:2,c:3}
let {a,...notA} = copy; // notA={b:2,c:3}
数组 简洁声明
//bad
let arr = new Array();
//good
let arr = [];
使用push代替直接分配元素给数组
//bad
let arr = [];
arr[arr.length] = "abc";
//good
arr.push("abc");    
扩展运算符...代替数组拷贝
//bad
let arr = [1,2,3];
let copy = [];
for(let i=0;i
转换类数组的对象为数组
let div = document.querySelectAll("div");
//good
let arr = Array.from(div);
//best
let arr = [...div]
数组方法中的return
//当function大括号只有一个表达式时,{}和rerun都可以省
//bad
[1,2,3].map(x=>{
    let y = x+1;
    return x*y
}) 
//good
[1,2,3].map(x=>x+1) 
解构赋值
//object
//good
function getFullName(user){
    let {firstName,lastName} = user;
    return `${firstName}${lastName}`
}
//best
function getFullName({firstName,lastName}){
    return `${firstName}${lastName}`
}

//array
let arr = [1,2,3,4];
//bad
let first = arr[0];
let sec = arr[1];
//good
[first,sec] = arr
函数的多个返回值用对象解构赋值
//bad
function processInput(input){
    return [let,top,right,bottom]
}
//good
function processInput(input){
    return {let,top,right,bottom}
}
//use
let {left,bottom} = processInput(input);
字符串 使用单引号
//bad
let str = "hello world";
//good
let str = "hello world"
             
尽量别转行
//有转行时,当然字符数不超过100的情况尽量别转行
//bad
let str = "hello world,"+
          "balabalabala";
//good

let str = "hello world,balabalabala"

字符串变量拼接
//bad
let str = "hello "+name+" !";
//good
let str =`hello ${name} !`;
函数 复杂名称的函数赋值给一个简洁变量名
  //bad
  let foo= function(){}
  function foo(){}
  //good
  let foo = function getPageFooComponent(){}
  //use
  foo();
别在if while等语句中声明函数
//bad
if(){
    function test(){}
}
//good
let test;
if(){
    test = ()=>{console.log("hello")}
}
别用arguments作为参数名
//bad
function foo(name,arguments){}
//good
function foo(name,arg){}
扩展运算符...代替arguments
//bad
function test(){
    let args = Array.portotype.slice.call(arguments);
    return args.join("");
}
//good
function test(...args){
    return args.join("");
}
默认参数
//bad
funtion test(opt){
    let opt = opt || {}
}
//good
function test(opt={}){

}
别在参数体里面计算
//bad
let a=1;
function test(b = a++){
    
}
将赋值的参数放在最后
//bad
function test(opt = {},name){
}
//good
function test(name,opt = {}){
}
别对参数重新赋值
//bad
function test(a){
    let a=1;
}
function test(a){
   if(!a){
    let a=1;
   }
}
//good
function test(a){
    let b = a || 1;
}
function test(a = 1){
  
}
类&构造方法 用class代替传统的prototype手动方法
//bad
function Queue(contents = []){
    this.queue = [contents];
}
Queue.prototype.pop = function(){
    let value = this.queue[0];
    this.queue.spice(0,1);
    return value;
}
//good
class Queue {
    constructor(contents = []){
        this.queue = [contents]
    }
    pop(){
        let value = this.queue[0];
        this.queue.spice(0,1);
        return value;
    }
}
用extend做继承
//good
class Dog extends Animal{
    yell(){
        return "wangwang"
    }
}
this的指向
 //bad
 Jedi.prototype.jump = function(){
     this.jumping = true;
     return true;
 }
 Jedi.prototype.setHeight= function(height){
     this.height = height;
 }
 let luck = new Jedi();
 luck.jump();
 luck.setHeight(20);
//good
class Jedi{
    jump(){
        this.jumping = true;
         return true;
    }
    setHeight(height){
        this.height = height;
    }
}
let luck = new Jedi();
luck.jump();
luck.setHeight(20);
子类的构造函数必须执行一次super函数
//bad
class test {
    constructor() {}//空constructor不需要
    
    getName() {
        return this.name;
    }
}
//bad
class test {
    constructor(...args) {
        super(...args)//只是为了继承constructor不需要
    }
}
//good
class test {
    constructor(...args) {
        super(...args)
        this.name = "key"
    }
}
模块 import/export
//bad
let AirbnbJavascriptGuide = require("./AirbnbJavascriptGuide ");
module.exports = AirbnbJavascriptGuide.es6;
//ok
import AirbnbJavascriptGuide  from "./AirbnbJavascriptGuide ";
export default AirbnbJavascriptGuide.es6;
//best
import {es6} from "./AirbnbJavascriptGuide ";
export default es6;
忌用通配符import
//bad
import * as AirbnbJavascriptGuide from "./AirbnbJavascriptGuide ";
//good
import AirbnbJavascriptGuide from "./AirbnbJavascriptGuide ";
别在import时同时export
//bad
export { es6 as default } from "./AirbnbJavascriptGuide ";
//good
import { es6 } from "./AirbnbJavascriptGuide ";
export default es6;
同一个地址放在一个import
//bad 
import foo form "foo";
...
import { name,age } from "foo";
//good
import foo,{ name,age } form "foo";
//best
import foo,{ 
            name,
            age 
            } form "foo";
只有一个export时 用export default
//bad
export function foo() {}
//good
export default foo() {}
不要在import时用Webpack loader
//bad
import foo from  "css!sass!foo.scss";
//good
import foo from "foo.css";
迭代遍历 用map、every、filter,find,findIndex,some,reduce等代替for-in,for-of
let numbers = [1,2,3,4]
//bad
let sum = 0;
for(let num of numbers){
    sum += num;
}    
//good
let sum = 0;
numbers.forEach(num => sum += num);

//bad
let increaseByOne = [];
for(let i = 0;i< numbers.length;i++){
    increaseByOne .push(numbers[i]+1);
}
//good
let increaseByOne = numbers.map(num => num + 1);
正确的constructor的书写
//good
let  test = function* (){
    //...
}
属性 通过.访问属性
let  luke = {
    jedi:true,
    age:28
}
//bad
let isJedi = luke["jedi"];
//good
let isJedi = luke.jedi;
通过变量访问属性时使用中括号 []
let  luke = {
    jedi:true,
    age:28
}
function getProp(prop) {
    return luke[prop];
}
let isJedi = getProp("jedi")

##变量##

用let和const声明变量
//good
let superPower = new SuperPower();
提升 var 声明会被提升至该作用域的顶部,但它们赋值不会提升
//bad
// 由于变量提升的原因,
// 在引用变量后再声明变量是可以运行的。
// 注:变量的赋值 `true` 不会被提升。
function example() {
  console.log(declaredButNotAssigned); // => undefined
  var declaredButNotAssigned = true;
}
匿名函数表达式的变量名会被提升,但函数内容并不会
function example() {
  console.log(anonymous); // => undefined

  anonymous(); // => TypeError anonymous is not a function

  var anonymous = function() {
    console.log("anonymous function expression");
  };
}    
函数声明的名称和函数体都会被提升
function example() {
  superPower(); // => Flying

  function superPower() {
    console.log("Flying");
  }
} 
比较和等号 优先使用 === 和 !== 而不是 == 和 !=
//good
if(a===1){}
使用简写
// bad
if (name !== "") {
  // ...stuff...
}

// good
if (name) {
  // ...stuff...
}

// bad
if (collection.length > 0) {
  // ...stuff...
}

// good
if (collection.length) {
  // ...stuff...
}
三元运算符通写在一行

// bad

const foo = maybe1 > maybe2
  ? "bar"
  : value1 > value2 ? "baz" : null;

// split into 2 separated ternary expressions
const maybeNull = value1 > value2 ? "baz" : null;

// better
const foo = maybe1 > maybe2
  ? "bar"
  : maybeNull;

// best
const foo = maybe1 > maybe2 ? "bar" : maybeNull;   
避免不必要的三元运算符
// bad
const foo = a ? a : b;
const bar = c ? true : false;
const baz = c ? false : true;

// good
const foo = a || b;
const bar = !!c;
const baz = !c;
混合运算时,尽量用括号,易懂
//bad
if(a || b && c){
    //...
}
//good
if(a || (b && c)){
    //...
}
代码块 用大括号包裹所有的多行代码块
// bad
if (test)
  return false;
// good
if (test){
  return false; 
}
条件语句 条件语句,换行将运算符放在最前面

// bad

if ((foo === 123 || bar === "abc") && doesItLookGoodWhenItBecomesThatLong() && isThisReallyHappening()) {
  thing1();
}
//good
if (
    (foo === 123 || bar === "abc") 
    && doesItLookGoodWhenItBecomesThatLong() 
    && isThisReallyHappening()
    ) {
  thing1();
}
注释
- 使用 /** ... */ 作为多行注释
- 使用 // 作为单行注释 ,上方空一行
- 使用 // FIXME: 标注问题
- 使用 // TODO: 标注问题的解决方式
逗号
- 行首逗号:不需要
- 结尾的逗号: 需要
分号
- 别省略分号
类型转换 字符串
// bad
const totalScore = new String(this.reviewScore); // typeof totalScore is "object" not "string"

// bad
const totalScore = this.reviewScore + ""; // invokes this.reviewScore.valueOf()

// bad
const totalScore = this.reviewScore.toString(); // isn’t guaranteed to return a string

// good
const totalScore = String(this.reviewScore);
数字
let inputValue= 4;

// bad
const val = new Number(inputValue);

// bad
const val = +inputValue;

// bad
const val = inputValue >> 0;

// bad
const val = parseInt(inputValue);

// good
const val = Number(inputValue);

// good
const val = parseInt(inputValue, 10);
布尔
const age = 0;

// bad
const hasAge = new Boolean(age);

// good
const hasAge = Boolean(age);

// good
const hasAge = !!age;    
命名规则
- 避免单字母命名。命名应具备描述性
- 使用驼峰式命名对象、函数和实例
- 使用ES6命名构造函数或类
class  User {
    constructor(options) {
        this.name = options.name;
    }
}
let good = new User({
    name:"yup"
});
- 使用下划线 _ 开头命名私有属性
- 使用箭头函数避免this引用错误
//bad 
function test(){
    let self = this;
    return function(){
        console.log(self);
    }
}
//good
function test(){
    return ()=>{
        console.log(this);
    }
}
- 文件只输出一个类,文件名必须和类名完全保持一致
// file contents
class CheckBox {
  // ...
}
export default CheckBox;

// in some other file
// bad
import CheckBox from "./checkBox";

// bad
import CheckBox from "./check_box";

// good
import CheckBox from "./CheckBox";
存取器
- 使用好get、set
- is、has
- 保持一致
// bad
dragon.age();

// good
dragon.getAge();
// bad
if (!dragon.age()) {
  return false;
}

// good
if (!dragon.hasAge()) {
  return false;
}
事件
// bad
$(this).trigger("listingUpdated", listing.id);

...

$(this).on("listingUpdated", function(e, listingId) {
  // do something with listingId
});    
// good
$(this).trigger("listingUpdated", { listingId : listing.id });

...

$(this).on("listingUpdated", function(e, data) {
  // do something with data.listingId
});
jQuery 使用 $ 作为存储 jQuery 对象的变量名前缀
// bad
const sidebar = $(".sidebar");

// good
const $sidebar = $(".sidebar");
缓存 jQuery 查询
const $sidebar = $(".sidebar");
对 DOM 查询使用层叠
$(".sidebar ul")
$(".sidebar > ul")
对有作用域的 jQuery 对象查询使用 find
// bad
$("ul", ".sidebar").hide();
// good
$sidebar.find("ul").hide();


参考:
https://github.com/airbnb/javascript

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/107303.html

相关文章

  • Json-path学习笔记<一>

    摘要:简介是用于结构化数据序列化的一种文本格式,包含种基础类型字符串,数字,布尔和和两种结构类型对象和数组。对象是一个由零或者多个名值对组成的无序集合,其中名值对中名是字符串类型,值则可以是字符串,数字,布尔,,对象或数组类型。 Json JavaScript Object Notation (JSON)是一个轻量级的,基于文本的,跨语言的数据交换格式。它从ECMAScript编程语言标准(...

    Vicky 评论0 收藏0
  • 前端资源系列(4)-前端学习资源分享&前端面试资源汇总

    摘要:特意对前端学习资源做一个汇总,方便自己学习查阅参考,和好友们共同进步。 特意对前端学习资源做一个汇总,方便自己学习查阅参考,和好友们共同进步。 本以为自己收藏的站点多,可以很快搞定,没想到一入汇总深似海。还有很多不足&遗漏的地方,欢迎补充。有错误的地方,还请斧正... 托管: welcome to git,欢迎交流,感谢star 有好友反应和斧正,会及时更新,平时业务工作时也会不定期更...

    princekin 评论0 收藏0
  • 重学前端学习笔记(二十七)--JavaScript的词法

    摘要:模板语法四种词法定义二空白符号空白符号分类或称是,是缩进符,字符串中写的。注意换行符会影响的两个重要语法特性自动插入分号和规则。 笔记说明 重学前端是程劭非(winter)【前手机淘宝前端负责人】在极客时间开的一个专栏,每天10分钟,重构你的前端知识体系,笔者主要整理学习过程的一些要点笔记以及感悟,完整的可以加入winter的专栏学习【原文有winter的语音】,如有侵权请联系我,邮箱...

    jayzou 评论0 收藏0
  • 重学前端学习笔记(二十七)--JavaScript的词法

    摘要:模板语法四种词法定义二空白符号空白符号分类或称是,是缩进符,字符串中写的。注意换行符会影响的两个重要语法特性自动插入分号和规则。 笔记说明 重学前端是程劭非(winter)【前手机淘宝前端负责人】在极客时间开的一个专栏,每天10分钟,重构你的前端知识体系,笔者主要整理学习过程的一些要点笔记以及感悟,完整的可以加入winter的专栏学习【原文有winter的语音】,如有侵权请联系我,邮箱...

    Hegel_Gu 评论0 收藏0

发表评论

0条评论

lufficc

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<