搜索
您的当前位置:首页正文

「内部分享·」JavaScript的优雅写法

来源:二三娱乐

Js为什么要写的优雅

  我经常会听到同事和网上沙雕网友说这段代码写的不优雅,当时也会附和表示是的。但是究其根本,心里始终对于「优雅」的定义很是模糊。随着时间的流逝,也逐渐抛到了脑后。但是越来越多的岗位JD和部门培训都对「优雅」有了要求,这也说明了更多的公司对于代码的书写有了更高的要求。如果你始终停滞不前,那么被首先淘汰就是你。
  周五部门内部组织分享,其中一个同事分享的主题就是「JS的优雅写法」,这引起了我对于「优雅」的思考。「优雅」最直观的表现就是看起来舒服,要做到这一点不难,那就是代码书写讲究一个规范,可以是你最习惯的换行,最习惯的变量命名等等。不要一个几百行代码,书写习惯换了好几次。做到这一点,那么自己看起来就能舒服了。但是这仅仅是最基本的,公司中的项目往往是不止一个人开发,更多的是协同开发。代码仅仅是自己看起来舒服还不行,还要做到其他人看起来也舒服。要做到这一点,就需要把每个人书写的习惯统一起来,形成团队规范。这也是大厂现在默认的代码规范,对于一些小公司(例如我们公司),并没有做到这点。
  上面讲了对外的「优雅」,下面再讲讲对内的「优雅」,核心就是一句话:用最合适的代码执行正确的逻辑。这句话意思是说,每一行代码要做到简洁,容易理解。例如有个场景需要进行多次条件判断,最粗糙的就是多个else if,稍微简洁点就是嵌套使用if else,更适合就是使用switch。判断对内的「优雅」很简单,自己看代码能够毫不费劲就能理解逻辑,并且没有「乱糟糟」,「多余」的感觉。

具体的优雅写法实例

  1. 运算符处换行时,运算符在新行的行首。
    在进行复杂的条件判断时,我们会使用到&&与||,这个使用过长的判断条件很容易让人心生厌恶,这个时候以一种漂亮的书写风格会更人让我们接受。
// good
if (user.isAuthenticated()
    && user.isInRole('admin')
    && user.hasAuthority('add-admin')
    || user.hasAuthority('delete-admin')
) {
    // Code
}
var result = number1 + number2 + number3
    + number4 + number5;

// bad
if (user.isAuthenticated() &&
    user.isInRole('admin') &&
    user.hasAuthority('add-admin') ||
    user.hasAuthority('delete-admin')) {
    // Code
}

var result = number1 + number2 + number3 +
    number4 + number5;
  1. boolean 类型的变量使用 is 或 has 开头
    这样做的好处是能一眼看出该变量就是一个布尔变量。

例如:
var isReady = false;
var hasMoreCommands = false;

  1. 尽可能使用简洁表达式
    在讲这个之前,先来复习一下JS中的数据类型及判断方式。
    JS数据类型
    如上图所示,JS中的数据类型分为基本数据类型引用数据类型引用数据类型一般也被直接叫做对象。对象可以看做是一个复合数据类型,我们可以用它来组装其他数据类型。其中被官方组装好的也是用的很广泛的主要是四种:Array(数组),Function(函数),RegExp(正则)和Date(日期)。
    类型判断
    那么在使用 if else时,对于条件的判断,我们尽可能使用简洁表达式:
// 字符串为空
// good
if (!name) {
    // ......
}
// bad
if (name === '') {
    // ......
}

// 字符串非空
// good
if (name) {
    // ......
}

// bad
if (name !== '') {
    // ......
}

// 数组非空
// good
if (collection.length) {
    // ......
}

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

// 布尔不成立
// good
if (!notTrue) {
    // ......
}

// bad
if (notTrue === false) {
    // ......
}

// null 或 undefined
// good
if (noValue == null) {
  // ......
}

// bad
if (noValue === null || typeof noValue === 'undefined') {
  // ......
}
  1. 如果函数或全局中的 else 块后没有任何语句,可以删除 else。
// good
function getName() {
    if (name) {
        return name;
    }

    return 'unnamed';
}

// bad
function getName() {
    if (name) {
        return name;
    }
    else {
        return 'unnamed';
    }
}
  1. 不要在循环体中包含函数表达式,事先将函数提取到循环体外
// good
function clicker() {
    // ......
}

for (var i = 0, len = elements.length; i < len; i++) {
    var element = elements[i];
    addListener(element, 'click', clicker);
}

// bad
for (var i = 0, len = elements.length; i < len; i++) {
    var element = elements[i];
    addListener(element, 'click', function () {});
}
  1. 对循环内多次使用的不变值,在循环外用变量缓存
// good
var width = wrap.offsetWidth + 'px';
for (var i = 0, len = elements.length; i < len; i++) {
    var element = elements[i];
    element.style.width = width;
    // ......
}

// bad
for (var i = 0, len = elements.length; i < len; i++) {
    var element = elements[i];
    element.style.width = wrap.offsetWidth + 'px';
    // ......
}
  1. 对有序集合进行顺序无关的遍历时,使用逆序遍历
    解释:逆序遍历可以节省变量,代码比较优化。
  var len = elements.length;
  while (len--) {
      var element = elements[len];
      // ......
      }
  1. 类型检测优先使用 typeof。对象类型检测使用 instanceof。null 或 undefined 的检 测使用 == null

  2. 转换成 number 时,通常使用+

// good 
+str;

//bad 
Number(str);
  1. 转换成 boolean 时,使用!!
var num = 3.14;
!!num;
  1. 属性访问尽量使用点语法
    解释:如非必须使用[]的情况,则建议优先使用点语法。通常在 JavaScript 中声明的对象,属性
    命名是使用 Camel 命名法,用 . 来访问更清晰简洁。
info.age;
info['more-info'];
  1. 清空数组使用 .length=0

  2. 使用 let 和 const 定义变量,尽量不使用 var
    解释:使用 let 和 const 定义时,变量作用域范围更明确。

  3. 使用 Object.keys 或 Object.entries 进行对象遍历
    解释:不建议使用 for .. in 进行对象的遍历,以避免遗漏 hasOwnProperty 产生的错误。

  4. 使用&&或||代替三元表达式
    逻辑与运算和逻辑或运算,实际上可以看做是条件运算的语法糖。同时JS
    中的三元运算符,也可以看做是条件运算的简写方式。我们可以使用&&和||替代,这样减少了代码量,还便于理解。

// 不推荐
let userName = localStorage.userName ? localStorage.userName : 'admin'
// 推荐
let userName = localStorage.userName || 'admin'
Top