ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

你中了几条,5个js编码的坏习惯

2021-12-06 23:58:01  阅读:257  来源: 互联网

标签:编码 object undefined ... 坏习惯 value js null JavaScript


更多文章,请关注微信公众号:前端css和js干货

在阅读js代码时,是否有过这样的感受:

  • 你几乎不明白代码的意思?

  • 代码使用了很多过时的JavaScript技巧?

  • 命名和编码风格比较随意? 这些是编码不良习惯的迹象。

本文列举了JavaScript中5个常见的不良编码习惯。 更重要的是,本文给出了如何改掉这些习惯的可行建议。

1. 不要使用隐式类型转换

JavaScript是一种弱类型的语言。如果使用得当,这是优点,因为它提供了灵活性。
大多数运算符 + - * / ==(不包括===)在处理不同类型的数据时使用隐式类型转换。 if (condition) {...}, while(condition) {...} 语句隐式地将条件转换为布尔值。
以下示例依赖于隐式类型转换。 我打赌你会感到困惑:

console.log("2" + "1"); // => "21"

console.log("2" - "1"); // => 1

console.log('' == 0); // => true

console.log(true == []); // -> false

console.log(true == ![]); // -> false

过度依赖隐式类型转换是一个坏习惯。首先,它使你的代码在某些情况下不太稳定。 其次,这使得难以复现也难以修复的bug变得更多。

下面是一个获取对象属性的函数。 如果该属性不存在,该函数返回一个默认值:

function getProp(object, propertyName, defaultValue) {

if (!object[propertyName]) {

    return defaultValue;

}

return object[propertyName];

}

const hero = {

    name: 'Batman',

    isVillian: false

};

console.log(getProp(hero, 'name', 'Unknown')); // => 'Batman'

getProp() 读取 name 属性的值,即“Batman”。

如果访问 isVillian属性会发生什么:

console.log(getProp(hero, 'isVillian', true)); // => true

这是一个错误。 即使hero的isVillian属性为false,函数getProp() 也会返回错误的true。
这是因为属性是否存在判断,依赖于通过 if (!object[propertyName]) {...} 隐式转换为布尔值。这类错误很难发现。 要修复该函数,需要明确数据的类型。

function getPropFixed(object, propertyName, defaultValue) {

if (object[propertyName] === undefined) {

    return defaultValue;

}

return object[propertyName];

}

const hero = {

    name: 'Batman',

    isVillian: false

};

console.log(getPropFixed(hero, 'isVillian', true)); // => false

object[propertyName] === undefined 验证属性访问器的运算结果是否为undefined。
旁注:第4.节建议避免直接使用 undefined。 因此可以使用in运算符改进上述方案 :

function getPropFixedBetter(object, propertyName, defaultValue) {

    if (!(propertyName in object)) {

        return defaultValue;

    }

    return object[propertyName];

}

建议:尽可能不要使用隐式类型转换。 相反,请确保变量和函数参数始终具有相同的类型。 必要时使用显式类型转换。

最佳实践列表:

  • 始终使用严格相等运算符 === 来执行比较

  • 不要使用松散相等运算符 ==

  • 加法运算符operand1+operand2:两个操作数都应该是数字或都是字符串

  • 算术运算符 - * / % :两个操作数都应该是数字

  • if (condition) {...}, while (condition) {...} 等语句:condition 应该是一个布尔值

  • 你可能会说这种方法需要编写更多代码……确实是这样! 但是通过明确的方法,你可以控制代码的行为。 另外,这也增加了可读性。

2.不要使用过时的 JavaScript 技巧

JavaScript 的有趣之处在于,它的创始人并没有预料到这种语言会变得如此流行。

基于 JavaScript 构建的应用程序的复杂性增长速度超过了语言的发展速度。 这种情况迫使开发人员使用 javaScript hacks来实现功能。

一个经典的例子是搜索一个数组是否包含一个元素。 使用 array.indexOf(item) !== -1来监测元素是否存在。
ECMAScript 2015及更高版本的功能变得越来越强大。 你可以使用新的语言特性安全地重构很多hacks。

使用ES2015方法 array.includes(item)重构array.indexOf(item) !== -1。

3.不要污染函数作用域

在ES2015之前,js变量是函数作用域的,因此,你可能养成了以函数作用域的方式声明所有变量的坏习惯,请看一个例子:

function someFunc(array) {

    var index, item, length = array.length;

    /*

    * Lots of code

    */

    for (index = 0; index < length; index++) {

        item = array[index];

        // Use `item`

    }

    return someResult;

}

变量 index、item 和 length 是函数作用域的。 但是这些变量会污染函数作用域,因为它们只在 for() 块作用域内是必需的。

随着块作用域变量声明关键字 let 和 const 的引入,我们应该尽可能地限制变量的生命周期。

让我们修正上述代码:

function someFunc(array) {

    /*

    * Lots of code

    */

    const length = array.length;

    for (let index = 0; index < length; index++) {

        const item = array[index];

        // Use `item`

    }

    return someResult;

}

index 和 item 变量仅存在于 for()循环块范围。 length移动到其使用点的附近。
重构后的代码更容易理解,因为变量没有分散在整个函数范围内。 它们存在于使用点附近。

在它们使用的块作用域内定义变量:
if块作用域

// 不好的做法
let message;
// ...
if (notFound) {
  message = 'Item not found';
  // Use `message`
}
// 好的做法
if (notFound) {
  const message = 'Item not found';
  // Use `message`
}

for块作用域

// 不好的做法
let item;
for (item of array) {
  // Use `item`
}
// 好的做法
for (const item of array) {
  // Use `item`
}

4.尽量避免 undefined 和 null

尚未赋值的变量被自动评估为undefined。 例如:

let count;

console.log(count); // => undefined

const hero = {

    name: 'Batman'

};

console.log(hero.city); // => undefined

count 变量已定义,但尚未用值初始化。 JavaScript 隐式分配给它 undefined。 访问不存在的属性 hero.city 时,也会返回 undefined。
为什么直接使用 undefined 是一个坏习惯? 因为当我们与undefined直接进行比较时,我们就有可能是在处理状态为未初始化的变量。
变量、对象属性、数组在使用之前必须用值初始化!
JavaScript 提供了很多方法来避免与undefine直接进行比较。

属性是否存在:

// 不好的做法
const object = {
  prop: 'value'
};
if (object.nonExistingProp === undefined) {
  // ...
}

// 好的做法
const object = {
  prop: 'value'
};
if ('nonExistingProp' in object) {
  // ...
}

对象默认属性

// 不好的做法
function foo(options) {
  if (object.optionalProp1 === undefined) {
    object.optionalProp1 = 'Default value 1';
  }
  // ...
}

// 好的做法
function foo(options) {
  const defaultProps = {
    optionalProp1: 'Default value 1'
  };
  options = {
    ...defaultProps,
    ...options
  };
  // ...
}

函数默认参数

// 不好的做法
function foo(param1, param2) {
  if (param2 === undefined) {
    param2 = 'Some default value';
  }
  // ...
}


// 好的做法
function foo(param1, param2 = 'Some default value') {
  // ...
}

你应该努力避免从函数中返回 null,更要避免使用null作为参数调用函数。 一旦 null 出现在你的调用堆栈中,你就必须在每个可能访问 null 的函数中检查变量是否为null。 这很麻烦也很容易出错,如下代码:

function bar(something) {

    if (something) {

        return foo({ value: 'Some value' });

    } else {

        return foo(null);

    }

}

function foo(options) {

    let value = null;

    if (options !== null) {

        value = options.value;

        // ...

    }

    return value;

}

尽量编写不涉及null值的代码。 一个替代方案是 try/catch 机制。
ALGOL 的发明者 Tony Hoare 曾说过:

我称其为我的十亿美元错误... 我正在为面向对象语言中的引用设计第一个综合类型系统。但我无法抗拒null引用的诱惑,仅仅因为它很容易实现。 这导致了无数错误、漏洞和系统崩溃,在过去的四十年里,这些问题可能造成了 10 亿美元的痛苦和损失。

“计算机科学最严重的错误”一文深入探讨了为什么 null会损害代码质量。

5.不要使用随意的编码风格

有什么比阅读具有随机编码风格的代码更令人生畏的呢? 你永远不知道会发生什么! 如果代码库包含许多开发人员的不同编码风格怎么办? 各式各样的人物涂鸦墙。

image.png

image.png

要求整个团队和应用程序代码库采用相同的编码风格。 它提高了代码的可读性。

可参考的编码风格示例:

  • Airbnb JavaScript 风格指南

  • 谷歌 JavaScript 风格指南

建议自动化验证代码风格:

  • 安装 eslint

  • 使用最适合你的编码风格配置 eslint

  • 设置一个预提交钩子,在提交之前运行 eslint验证。

6.总结

编写高质量和干净的代码需要纪律越是,克服不良的编码习惯。
JavaScript 是一种弱类型语言,有很大的灵活性。 但是你必须清楚自己所使用的特性。 建议是避免隐式类型转换并减少 undefined 和 null 的使用。
最近几年js语言发展得非常快。 找到棘手的代码,并使用最新的 JavaScript特性重构它。
代码库中一致的编码风格有利于可读性。
你还知道 JavaScript 中还有哪些不好的编码习惯?

作者:dmitripavlutin 译者:前端css和js干货 来源:Dmitri Pavlutin

 

标签:编码,object,undefined,...,坏习惯,value,js,null,JavaScript
来源: https://blog.csdn.net/hahaqqqa/article/details/121759101

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有