写更漂亮的javascript

用更合理的方式写 JavaScript

目录

  1. 声明变量
  2. 对象
  3. 数组
  4. 字符串
  5. 函数
  6. 箭头函数
  7. 模块
  8. 迭代器和生成器
  9. 属性
  10. 变量
  11. 提升
  12. 比较运算符和等号
  13. 代码块
  14. 注释
  15. 空白
  16. 逗号
  17. 分号
  18. 类型转换
  19. 命名规则

声明变量

  • 1.1 使用let和const代替var
    • 不会变的声明用const
    //bad 
    var $cat = $('.cat')//good
    const $cat = $('.cat')
    
    • 会变动的声明用let
    //bad 
    var count = 1
    if (count<10) {count += 1
    }//good
    let count = 1
    if (count<10) {count += 1
    }
    
  • 1.2 将所有的 constlet 分组

    为什么?当你需要把已赋值变量赋值给未赋值变量时非常有用。

    // bad
    let i, len, dragonball,items = getItems(),goSportsTeam = true;// bad
    let i;
    const items = getItems();
    let dragonball;
    const goSportsTeam = true;
    let len;// good
    const goSportsTeam = true;
    const items = getItems();
    let dragonball;
    let i;
    let length;
  • 1.3 在你需要的地方给变量赋值,但请把它们放在一个合理的位置。

    为什么?letconst 是块级作用域而不是函数作用域。

    // bad - unnecessary function call
    const checkName = function (hasName) {const name = getName();if (hasName === 'test') {return false;}if (name === 'test') {this.setName('');return false;}return name;
    };// good
    const checkName = function (hasName) {if (hasName === 'test') {return false;}const name = getName();if (name === 'test') {this.setName('');return false;}return name;
    };

    ⬆ 返回目录

对象 Objects

  • 2.2 创建有动态属性名的对象时,使用可被计算的属性名称。

    为什么?因为这样可以让你在一个地方定义所有的对象属性。

    const getKey = function (k) {return `a key named ${k}`;
    };// bad
    const obj = {id: 1,name: 'San Francisco',
    };
    obj[getKey('enabled')] = true;// good
    const obj = {id: 1,name: 'San Francisco',[getKey('enabled')]: true,
    };

数组 Arrays

⬆ 返回目录

字符串 Strings

  • 4.5 不要在字符串中使用 eval(),这个方法有要多缺陷。eslint: no-eval

⬆ 返回目录

函数 Functions

  • 5.6 直接给函数的参数指定默认值,不要使用一个变化的函数参数。

    // really bad
    const handleThings = function (opts) {// 不!我们不应该改变函数参数。// 更加糟糕: 如果参数 opts 是 false 的话,它就会被设定为一个对象。// 但这样的写法会造成一些 Bugs。//(译注:例如当 opts 被赋值为空字符串,opts 仍然会被下一行代码设定为一个空对象。)opts = opts || {};// ...
    };// still bad
    const handleThings = function (opts) {if (opts === void 0) {opts = {};}// ...
    };// good
    const handleThings = function (opts = {}) {// ...
    };
  • 5.7 直接给函数参数赋值时需要避免副作用。

    为什么?因为这样的写法让人感到很困惑。

    var b = 1;
    // bad
    const count = function (a = b++) {console.log(a);
    };
    count();  // 1
    count();  // 2
    count(3); // 3
    count();  // 3

  • 5.10 优先使用扩展运算符 ... 来调用参数可变的函数。 eslint: prefer-spread

    为什么? 这样写代码更干净,不必提供上下文。

    ```javascript
    // bad
    const x = [1, 2, 3, 4, 5];
    console.log.apply(console, x);

    // good
    const x = [1, 2, 3, 4, 5];
    console.log(...x);

    // bad
    new (Function.prototype.bind.apply(Date, [null, 2016, 8, 5]));

    // good
    new Date(...[2016, 8, 5]);

⬆ 返回目录

箭头函数

⬆ 返回目录

模块 Modules

  • 7.1 总是使用模组 (import/export) 而不是其他非标准模块系统。你可以编译为你喜欢的模块系统。

    为什么?模块化是未来趋势。

    // bad
    const AirbnbStyleGuide = require('./AirbnbStyleGuide');
    module.exports = AirbnbStyleGuide.es6;// ok
    import AirbnbStyleGuide from './AirbnbStyleGuide';
    export default AirbnbStyleGuide.es6;// best
    import {es6} from './AirbnbStyleGuide';
    export default es6;
  • 7.2 不要使用通配符 import。

    为什么?这样能确保你只有一个默认 export。

    // bad
    import * as AirbnbStyleGuide from './AirbnbStyleGuide';// good
    import AirbnbStyleGuide from './AirbnbStyleGuide';
  • 7.3 不要从 import 中直接 export。

    为什么?虽然一行代码简洁明了,但让 import 和 export 各司其职让事情能保持一致。

    // bad
    // filename es6.js
    export {es6 as default} from './airbnbStyleGuide';// good
    // filename es6.js
    import {es6} from './AirbnbStyleGuide';
    export default es6;

  • 7.4 不要多次 import 同一个文件。eslint: no-duplicate-imports

    Why? 多个地方引入同一个文件会使代码难以维护。

    // bad
    import foo from 'foo';
    // … some other imports … //
    import {named1, named2} from 'foo';// good
    import foo, {named1, named2} from 'foo';// good
    import foo, {named1,named2,
    } from 'foo';

⬆ 返回目录

Iterators and Generators

⬆ 返回目录

属性 Properties

⬆ 返回目录

变量 Variables

  • 11.1 不要链式的给变量赋值。eslint: no-multi-assign

    为什么?链式变量赋值会创建隐式的全局变量。

    // bad
    (function example() {// JavaScript interprets this as// let a = ( b = ( c = 1 ) );// The let keyword only applies to variable a; variables b and c become// global variables.let cat = dog = bird = 1;
    }());console.log(cat); // throws ReferenceError
    console.log(dog); // 1
    console.log(bird); // 1// good
    (function example() {let cat = 1;let dog = cat;let bird = cat;
    }());console.log(cat); // throws ReferenceError
    console.log(dogb); // throws ReferenceError
    console.log(bird); // throws ReferenceError// the same applies for `const`

  • 10.2 避免使用累加和累减符号 (++, --)。 eslint no-plusplus

    为什么?根据 eslint 文档,累加和累减会受到自动插入分号的影响,并可能导致一些意外情况发生。

    // bad
    const array = [1, 2, 3];
    let num = 1;
    num++;
    --num;let sum = 0;
    let truthyCount = 0;
    for (let i = 0; i < array.length; i++) {let value = array[i];sum += value;if (value) {truthyCount++;}
    }// good
    const array = [1, 2, 3];
    let num = 1;
    num += 1;
    num -= 1;const sum = array.reduce((a, b) => a + b, 0);
    const truthyCount = array.filter(Boolean).length;

  • 10.3 避免使用魔法数字(白名单如下)。 eslint no-magic-numbers

    为什么?魔法数字让人难难以明白开发者的意图是什么,破坏代码的可读性和可维护性。

    // 以下为魔法数字白名单
    let magicNumberIgnore = [];// baisc number
    magicNumberIgnore = magicNumberIgnore.concat([-1, 0, 100, 1000, 10000
    ]);// datetime number
    magicNumberIgnore = magicNumberIgnore.concat([12, 24, 60, 3600
    ]);// httpcode number
    magicNumberIgnore = magicNumberIgnore.concat([200,301, 302, 303, 304,400, 401, 402, 403, 404,500, 501, 502, 503, 504
    ]);// bit number
    magicNumberIgnore = magicNumberIgnore.concat([1024
    ]);// number 1-49
    for (i = 1; i <= 49; i++) {if (magicNumberIgnore.indexOf(i) === -1) {magicNumberIgnore.push(i);}}
    // bad
    let soldNum = 102;
    let initNum = 80;// good
    const APPLE = 102;
    const STOCK = 80;
    let soldNum = APPLE;
    let initNum = STOCK;

⬆ 返回目录

Hoisting

⬆ 返回目录

比较运算符和等号

  • 12.1 使用 ===!== 而不是 ==!=。eslint: eqeqeq

  • 12.2 条件表达式例如 if 语句通过抽象方法 ToBoolean 强制计算它们的表达式并且总是遵守下面的规则:

    • 对象 被计算为 true
    • Undefined 被计算为 false
    • Null 被计算为 false
    • 布尔值 被计算为 布尔的值
    • 数字 如果是 +0、-0、或 NaN 被计算为 false, 否则为 true
    • 字符串 如果是空字符串 '' 被计算为 false,否则为 true
    if ([0] && []) {// true// an array (even an empty one) is an object, objects will evaluate to true
    }
  • 12.3 布尔值使用简写,但是需要显示比较字符串和数字。

    // bad
    if (isValid === true) {// ...
    }// good
    if (isValid) {// ...
    }// bad
    if (name) {// ...
    }// good
    if (name !== '') {// ...
    }// bad
    if (collection.length) {// ...
    }// good
    if (collection.length > 0) {// ...
    }
  • 12.4 想了解更多信息,参考 Angus Croll 的 Truth Equality and JavaScript。

  • 12.5 当 casedefault 包含的子句中有词法声明时,用大括号包裹。(例如 let, const, function, and class). eslint: no-case-declarations

    为什么?词法声明在整个 switch 块中是可见的,但只有在代码执行到 case 中变量被赋值时才会被初始化,当多个 case 子句中定义相同的变量是时会出现问题。

    // bad
    switch (foo) {case 1:let xx = 1;break;case 2:const yy = 2;break;case 3:const func = function () {// ...};break;default:get();
    }// good
    switch (foo) {case 1: {let xx = 1;break;}case 2: {const yy = 2;break;}case 3: {const func = function () {// ...};break;}case 4:bar();break;default: {get();}
    }

  • 12.6 三元表达式不能嵌套使用。 eslint: no-nested-ternary

    // 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;

  • 12.7 避免出现不必要的三元表达式。 eslint: no-unneeded-ternary

    // bad
    const foo = maybe1 ? maybe1 : maybe2;
    const bar = correct ? true : false;
    const baz = wrong ? false : true;// good
    const foo = maybe1 || maybe2;
    const bar = !!correct;
    const baz = !wrong;

  • 12.8 当混用操作符时,要用括号括起来。唯一的例外是标准的算术运算符 (+, -, *, & /),因为它们很容易理解。 eslint: no-mixed-operators

    为什么?这提高了代码的可读性,并且使得开发者的意图很清晰。

    // bad
    const foo = p1 && p2 < 0 || p3 > 0 || p4 + 1 === 0;// bad
    const bar = p1 ** p2 - 5 % p4;// bad
    // one may be confused into thinking (p1 || p2) && p3
    if (p1 || p2 && p3) {return p4;
    }// good
    const foo = (p1 && p2 < 0) || p3 > 0 || (p4 + 1 === 0);// good
    const bar = (p1 ** p2) - (5 % p4);// good
    if (p1 || (p2 && p3)) {return p4;
    }// good
    const bar = p1 + (p2 / p3 * p4);

⬆ 返回目录

代码块 Blocks

  • 13.3 如果 if 代码块中肯定会执行 return 语句,那么后面的 else 就没必要写了。如果在 else if 代码块中又有 if,并且 if 代码块会执行return 语句,那么可以分拆成多个 if 代码块。 eslint: no-else-return

    // bad
    const foo = function () {if (correct) {return correct;} else {return wrong;}
    };// bad
    const cats = function () {if (correct) {return correct;} else if (wrong) {return wrong;}
    };// bad
    const dogs = function () {if (correct) {return correct;} else {if (wrong) {return wrong;}}
    };// good
    const foo = function () {if (correct) {return correct;}return wrong;
    };// good
    const cats = function () {if (correct) {return correct;}if (wrong) {return wrong;}return false;
    };//good
    const dogs = function (correct) {if (correct) {if (confuse) {return wrong;}} else {return confuse;}
    };

⬆ 返回目录

注释 Comments

⬆ 返回目录

空格 Whitespace

  • 15.8 不要在 block 代码块中加空行。 eslint: padded-blocks

    // bad
    const bar = function () {console.log(foo);};// bad
    if (baz) {console.log(qux);
    } else {console.log(foo);}// bad
    class Foo {constructor(bar) {this.bar = bar;}
    }// good
    const bar = function () {console.log(foo);
    };// good
    if (baz) {console.log(qux);
    } else {console.log(foo);
    }

  • 15.9 不要在小括号中加空格。 eslint: space-in-parens

    // bad
    const bar = function ( foo ) {return foo;
    };// good
    const bar = function (foo) {return foo;
    };// bad
    if ( foo ) {console.log(foo);
    }// good
    if (foo) {console.log(foo);
    }

  • 15.10 不要在中括号中加空格。 eslint: array-bracket-spacing

    // bad
    const foo = [ 1, 2, 3 ];
    console.log(foo[ 0 ]);// good
    const foo = [1, 2, 3];
    console.log(foo[0]);

  • 15.11 不要在大括号中加空格。 eslint: object-curly-spacing

    // bad
    const foo = { clark: 'kent' };// good
    const foo = {clark: 'kent'};

  • 15.12 尽量控制一行代码在==100==个字符以内(包括空格)。字符串、字符串模板和 URL 不受限制。eslint: max-len

    为什么?这么做保证了可读性和可维护性。

    // bad
    const foo = jsonData && jsonData.foo && jsonData.foo.bar && jsonData.foo.bar.baz && jsonData.foo.bar.baz.quux && jsonData.foo.bar.baz.quux.xyzzy;// bad
    $.ajax({ method: 'POST', url: 'https://airbnb.com/', data: { name: 'John' } }).done(() => console.log('Congratulations!')).fail(() => console.log('You have failed this city.'));// good
    const foo = jsonData&& jsonData.foo&& jsonData.foo.bar&& jsonData.foo.bar.baz&& jsonData.foo.bar.baz.quux&& jsonData.foo.bar.baz.quux.xyzzy;// good
    $.ajax({method: 'POST',url: 'https://airbnb.com/',data: {name: 'John',},
    }).done(() => {// do something...}).fail(() => {// do something...});

⬆ 返回目录

逗号 Commas

⬆ 返回目录

分号 Semicolons

⬆ 返回目录

类型转换

⬆ 返回目录

命名规则

⬆ 返回目录

转载于:https://www.cnblogs.com/huyuzhu/p/9138790.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/251638.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

笔试小结---树

平衡二叉树(Balanced Binary Tree):又被称为AVL树,且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1&#xff0c;并且左右两个子树都是一棵平衡二叉树。 二叉搜索树&#xff1a;是一颗二叉树&#xff0c;可能为空;若非空,则满足以下特征: 1.每个元素有一…

iOS 快速实现分页界面的搭建

级别&#xff1a; ★★☆☆☆ 标签&#xff1a;「iOS」「分页」「QiPageMenuView」 作者&#xff1a; 沐灵洛 审校&#xff1a; QiShare团队 iOS 快速实现分页界面的搭建 项目中我们经常会遇到滚动分页的设计效果&#xff0c;被用来对不同数据界面的展示进行分类。我们先可以来…

java中String的常用方法

java中String的常用方法 转自&#xff1a;http://archer-zhou.iteye.com/blog/443864 java中String的常用方法1、length() 字符串的长度例&#xff1a;char chars[]{a,b.c};String snew String(chars);int lens.length();2、charAt() 截取一个字符例&#xff1a;char ch;ch&quo…

笔试小结---非对称加密算法

非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey).公开密钥和私有密钥是一对,如果公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥进行加密,那么只有用对应的公开密钥才能解密. 非对称加密算法的保密性比较好,它消除了最终用户交换…

登录令牌 Token 介绍

Token值介绍 token 值: 登录令牌.利用 token 值来判断用户的登录状态.类似于 MD5 加密之后的长字符串. 用户登录成功之后,在后端(服务器端)会根据用户信息生成一个唯一的值.这个值就是 token 值. 基本使用: 在服务器端(数据库)会保存这个 token 值,以后利用这个 token 值来检索…

java-number

通常&#xff0c;当我使用number类型的时候&#xff0c;我们可以使用原始数据类型例如byte&#xff0c;int,long,double等 int i 5000; float b 13.65; double m 0xaf; 所有包装类&#xff08;整型&#xff0c;长型&#xff0c;字节型&#xff0c;双精度型&#xff0c;浮点型&a…

您的浏览器没有获得Java Virtual Machine(JVM)支持。可能由于没有安装JVM或者已安装但是没有启用。请安装JVM1.5或者以上版本,如果已安装则启用它。...

您的浏览器没有获得Java Virtual Machine(JVM)支持。可能由于没有安装JVM或者已安装但是没有启用。请安装JVM1.5或者以上版本&#xff0c;如果已安装则启用它。 https://www.java.com/zh_CN/download/faq/remove_olderversions.xml https://jingyan.baidu.com/article/6d704a13…

指令定义

restict&#xff1a;它告诉AngularJS这个指令在DOM中可以以何种形式被声明。 E(元素&#xff09; <my-directive> </mydirective>A(属性) <div my-directive“expression”> </div>C(类名) <div class“my-directive:expression;”> </div>…

MyBatis学习总结(9)——使用MyBatis Generator自动创建代码

2019独角兽企业重金招聘Python工程师标准>>> 由于MyBatis属于一种半自动的ORM框架&#xff0c;所以主要的工作就是配置Mapping映射文件&#xff0c;但是由于手写映射文件很容易出错&#xff0c;所以可利用MyBatis生成器自动生成实体类、DAO接口和Mapping映射文件。这…

[BZOJ2125]最短路(圆方树DP)

题意&#xff1a;仙人掌图最短路。 算法&#xff1a;圆方树DP&#xff0c;$O(n\log nQ\log n)$ 首先建出仙人掌圆方树&#xff08;与点双圆方树的区别在于直接连割边&#xff0c;也就是存在圆圆边&#xff09;&#xff0c;然后考虑点u-v的最短路径&#xff0c;显然就是&#xf…

20162317 2017-2018-1 《程序设计与数据结构》第8周学习总结

20162317 2017-2018-1 《程序设计与数据结构》第8周学习总结 教材学习内容总结 1、二叉查找树的定义、性质2、向二叉查找树中添加元素的方法3、在二叉查找树中删除元素的方法4、旋转的定义、方法、意义 教材学习中的问题和解决过程问题1&#xff1a;我在17章中看到这么一句话&a…

ES6模块的转码

浏览器目前还不支持ES6模块,为了实现立刻使用,我们可以将其转为ES5的写法.除了Babel可以用来转码,还有以下两个方法也可以用来转码: ES6 moudule transpilerSystemJS ES6 moudule transpiler是square公司开源的一个转码器,可以将ES6模块转为CommonJS模块或AMD模块,从而在浏览器…

Java基础学习总结(22)——异常处理

2019独角兽企业重金招聘Python工程师标准>>> 一、异常的概念 异常指的是运行期出现的错误&#xff0c;也就是当程序开始执行以后执行期出现的错误。出现错误时观察错误的名字和行号最为重要。 1 package cn.javastudy.summary;2 3 public class TestEx{4 5 …

XAML中格式化日期

要求被格式化数据的类型是DateTime StringFormatyyyy-MM-dd StringFormat{}{0:yyyy-MM-dd}转载于:https://www.cnblogs.com/changbaishan/p/9144584.html

130242014045 林承晖 第2次实验

软件体系结构的第二次实验&#xff08;解释器风格与管道过滤器风格&#xff09; 一、实验目的 1&#xff0e;熟悉体系结构的风格的概念 2&#xff0e;理解和应用管道过滤器型的风格。 3、理解解释器的原理 4、理解编译器模型 二、实验环境 硬件&#xff1a; 软件&#xff1a;P…

AnularJS1事件

在Web应用的组件是松耦合的情况下&#xff0c;比如需要用户验证然后处理授权&#xff0c;即时的通信不总是可行的&#xff0c;因为组件没有耦合在一起。 例如&#xff0c;如果后端对一个请求返回了状态码401&#xff08;表明一个未经授权的请求&#xff09;&#xff0c;我们期望…

Java基础学习总结(8)——super关键字

2019独角兽企业重金招聘Python工程师标准>>> 一、super关键字 在JAVA类中使用super来引用父类的成分&#xff0c;用this来引用当前对象&#xff0c;如果一个类从另外一个类继承&#xff0c;我们new这个子类的实例对象的时候&#xff0c;这个子类对象里面会有一个父类…

conda镜像

转自https://blog.csdn.net/guilutian0541/article/details/81004769 conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main conda config --set show…

Java基础学习总结(17)——线程

2019独角兽企业重金招聘Python工程师标准>>> 一、线程的基本概念 线程理解&#xff1a;线程是一个程序里面不同的执行路径 每一个分支都叫做一个线程&#xff0c;main()叫做主分支&#xff0c;也叫主线程。 程只是一个静态的概念&#xff0c;机器上的一个.class文件…

(转)MySQL自带的性能压力测试工具mysqlslap详解

mysqlslap 是 Mysql 自带的压力测试工具&#xff0c;可以模拟出大量客户端同时操作数据库的情况&#xff0c;通过结果信息来了解数据库的性能状况 mysqlslap 的一个主要工作场景就是对数据库服务器做基准测试 例如我们拿到了一台服务器&#xff0c;准备做为数据库服务器&#x…