写好 Javascript 的 14 个技巧

以下是我最喜欢的一些编写更干净的 Javascript 代码的技巧,跳过聪明的保持简单。

1. 忘掉 var

使用 const 或 let 声明所有变量。根据经验,默认情况下使用 const,否则如果需要重新赋值变量,请使用 let

应避免使用 var 关键字,因为它几乎是无范围的,会导致潜在的范围错误。

例如:最佳做法是在创建变量时初始化变量,以便您和您的团队可以确保没有未使用的变量。

// ❌ Avoid this
var old = "";// ✅ Do this
const immutable = "John";
let counter = 1;
counter++; // counter === 2;// Declare objects and arrays as const to prevent type change
const user = {firstname: "John", lastname: "Doe"};
const users = ["Mac", "Roe"];

2. 严格相等

严格相等运算符 (===) 与相等运算符相同,检查其两个操作数是否相等,并返回布尔结果。但与相等运算符 (==) 不同,严格相等运算符 (===) 始终认为不同类型的操作数是不同的。

例如:0为 false,在非严格相等运算符的情况下会错误地等于 false。

// ❌ Avoid this
1 == "1"; // true
0 == false; // true// ✅ Do this
1 === 1; // true
1 === "1"; // false
0 === false; // false

3. 避免使用原始值对象构造函数

原始对象与原始对象构造函数严格不同,这使得
它们在包装在对象中时更难检查严格相等性。

它们基本上是等价的,但其实不相等。

// ❌ Avoid this
const stringObject = new String("Charly");// ✅ Do this
const stringPrimitive = "Charly";// Equality check
stringPrimitive === stringObject; // false 
new Number(1) === 1; // false
new Boolean(true) === true; // false

4. 利用对象结构

对象结构是一种速记符号,允许您动态定义对象或数组。

从而避免重复,提高可读性并防止错误,因为我们无法推断其背后的逻辑,我们当前是在初始化变量还是更新变量?

// ❌ Avoid this
const user = new Object(); // {}
user.firstname = "John"; // { firstname: "John" }
user.lastname = "Doe"; // { firstname: "John", lastname: "Doe" }// ✅ Do this
const user = { firstname: "John", lastname: "Doe" 
};// ❌ Avoid this
const fruits = new Array(); // []
fruits.push("banana"); // ["banana"]
fruits.push("mango"); // ["banana", "mango"]// ✅ Do this
const fruits = ["banana", "mango"];

5. 使用模板文字合并字符串

将字符串合并是一件很痛苦的事情,尤其是在组合字符串和变量时。

为了简化此过程,您可以使用模板文本(用反引号标记),只要字符串和变量值 (${}) 包围,它就会同时接受字符串变量

const firstname = "John";// ❌ Avoid this
let greeting = "Hello, " + firstname; // Hello, John// ✅ Do this
greeting = `Hello, ${firstname}`; // Hello, John

6. 使用分号作为行终止

使用分号进行行终止始终是一种很好的做法。

如果您忘记了它,您不会收到警告,因为在大多数情况下,它会被 JavaScript 解析器插入。但是,如果没有它,你怎么知道一个表情何时结束呢?

以for循环为例:

// ✅ Do this
for (let i = 0; i < numbers.length; i++) {console.log(numbers[i]);
}

您将无法执行以下操作,因为解析器认为它是一个表达式,而实际上它是三个独立的表达式:

// ❌ Not this
for (let i = 0 i < numbers.length i++) {console.log(numbers[i]);
} // Uncaught SyntaxError: Unexpected identifier

7.使用对象参数而不是多个参数

我认为在我的函数中定义太多参数是一种代码坏味道。即使参数具有默认值或可选参数,我们也可以举个例子:

// ❌ Avoid this
function avatarUrl(avatar, format = "small", caption = true) {// Does something
}avatarUrl(user.avatar, 'thumb', false)

当您使用此函数时,很难知道使用了哪些参数以及如何使用。最后一个参数 false 在这里代表什么?

不知道,我们必须打开函数定义才能知道。
如果需要更改参数的顺序,会发生什么情况?好吧,您必须更改所有函数调用。

对于对象,顺序无关紧要:

// ✅ Do this
function avatarUrl(avatar, options={format: 'small', caption: true}) {// Does something
}avatarUrl(user.avatar, {format: "thumb", caption: false
})

8.尽早 return

嵌套条件使代码难以理解,但您可以通过提前返回来使用 guard 子句轻松避免它。

Guard 子句将允许您删除大部分 else 条件,使您的代码像纯文本一样可读。

// ❌ Avoid this
function doSomething() {if (user) {if (user.role === "ADMIN") {return 'Administrator';} else {return 'User';}} else {return 'Anonymous';}
}// ✅ Do this
function doSomething() {if (!user) return 'Anonymous'if (user.role === "ADMIN") return 'Administrator'return 'User'
}

9. 学习和使用工具的强大功能

Javascript 在数组对象字符串上提供了许多内置函数。

查找并学习它们,以享受提供的全部功能。

// ❌ Avoid this
const users = [{username: "JohnDoe",admin: false},{username: "Todd",admin: true},
];
const admins = [];function getAdmins() {users.forEach((user) => {if (user.admin) admins.push(user)})return admins
}// ✅ Do this
function getAdmins() {return users.filter((user) => user.admin)
}

10. 为人编写代码,而不是为计算机编写代码

让我们假设一下,我们大多数人都不善于注意到差异,我们可能需要几秒钟才能注意到逻辑非(!

让我们举个例子:

const users = [{username: "JohnDoe",admin: falseenabled: true},{username: "Todd",admin: trueenabled: true},
];// ❌ Avoid this
const members = users.filter(u => u.enabled).map(u => !u.admin)
const admins = users.filter(u => u.enabled).map(u => u.admin)// ✅ Do this
const enabledUsers = users.filter(u => u.enabled)
const members = enabledUsers.map(u => !u.admin)
const admins = enabledUsers.map(u => u.admin)

members 和 admins 分配的区别仅在逻辑非 (!),如果您需要更改一个分配,则还需要更改另一个分配。

另一个例子,不要使用魔法数字。请改用显式变量:

// ❌ Avoid this
function price_with_taxes(price) {return price * 1.2
}// ✅ Do this
const taxRate = 1.2
function price_with_taxes(price) {return price * taxRate
}

11.避免缩写

无论你是为事件写 e还是为票证写 t 都不会提高你的工作效率,但它确实会降低可读性并降低即时理解力。

// ❌ Avoid this
function someFunction() {events.forEach(e => {e.tickets.forEach(t => {`${e.name} for ${t.full_name}`})})
}// ✅ Do this
function someFunction() {events.forEach(event => {event.tickets.forEach(ticket => {`${event.name} for ${ticket.full_name}`})})
}

在这里,您不必猜测 e 和 t 代表什么,您只需阅读它即可。
编码非常复杂,足以让你的大脑变得异常复杂。这也适用于变量、类、方法......

不过也有少数例外,可以在 for 循环中使用像 i 这样广泛使用的缩写。

12.避免无用和否定的条件

条件就像你大脑的备忘录,因为你需要在逐步执行每一行代码时记住它们,以便了解发生了什么。

幸运的是,由于我最喜欢的 ES6 运算符 optional,它们中的大多数都可以简化。

// ❌ Avoid this
function doSomething(params) {if (params && params.filter) return 'Foo'return 'Bar'
}// ✅ Do this
function doSomething(params) {if (params?.filter) return 'Foo'return 'Bar'
}

我不知道你是怎么想的,但每次我看到一个逻辑非(!),它都会让我的大脑停顿一秒钟,对我来说,阅读这样的东西感觉更自然:

如果用户是管理员,那么我们会这样做

而不是:

如果用户不是管理员,那么我们会这样做。

// ❌ Avoid this
function doSomething(user) {if (!user || !user.admin) {// Case where no user or not admin} else {// Case where user and user is admin}
}// ✅ Do this
function doSomething(user) {if (user && user.admin) {// Case where user and user is admin} else {// Case where no user or not admin}
}

13. 用 for...of 而不是 for 循环

使用 for...of 语句而不是经典的 for 循环就是这样一种 JavaScript 改进。

ES6 引入了这种语法,它包含一个内置的迭代器,因此您不必定义自己的变量,而是将其递增,直到达到某个长度值:

let users = ["Fedor Emelianenko", "Cyril Gane", "Conor McGregor"];// ❌ Avoid this
// This avoids length behind reavaluated at every iteration
let usersCount = users.length;
for (let i = 0; i < usersCount; i++) {console.log(users[i]);
}// ✅ Do this
for(let user of users) {console.log(user);
}

请注意它的可读性有多强!而且你不必关心所有这些笨拙的逻辑(let i = 0;i < usersCount;i++),尽管你可能需要它来处理某些特定的用例,比如不规则的间隔。

14. 可读代码胜过聪明代码

永远记住,你是在与其他开发人员以及你未来的自己一起编写代码。您不希望创建比编写代码时要解决的问题更多的问题。

不要为了炫耀自己的技能而编写代码,要编写每个人都能理解和调试的代码。

Keep it simple!

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

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

相关文章

PostgreSQL常用命令

数据库版本 :9.6.6 注意 :PostgreSQL中的不同类型的权限有 SELECT,INSERT,UPDATE,DELETE,TRUNCATE,REFERENCES,TRIGGER,CREATE,CONNECT,TEMPORARY,EXECUTE 和 USAGE。 1. 登录PG数据库 以管理员身份 postgres 登陆,然后通过 #psql -U postgres #sudo -i -u postgres …

数据手套:手势识别技术的多元化应用

科技日新月异&#xff0c;虚拟现实不再局限于依赖头显来探索虚拟世界。数据手套的广泛应用使人们能够更轻松地与虚拟世界产生真实互动。在此之中&#xff0c;手势识别作为一种直观、自然的人机交互方式&#xff0c;受到了广泛关注。数据手套作为一种能够精确捕捉手指运动的人机…

使用React 18和WebSocket构建实时通信功能

1. 引言 WebSocket是一种在Web应用中实现双向通信的协议。它允许服务器主动向客户端推送数据&#xff0c;而不需要客户端发起请求。在现代的实时应用中&#xff0c;WebSocket经常用于实时数据传输、聊天功能、实时通知和多人协作等场景。在本篇博客中&#xff0c;我们将探索如…

Flink系列之:监控Checkpoint

Flink系列之&#xff1a;监控Checkpoint 一、概览二、概览&#xff08;Overview&#xff09;选项卡三、历史记录&#xff08;History&#xff09;选项卡四、历史记录数量配置五、摘要信息&#xff08;Summary&#xff09;选项卡六、配置信息&#xff08;Configuration&#xff…

@RequestMapping注解与其派生注解接收参数详解

一、前言 根据 HTTP 标准&#xff0c;HTTP 请求可以使用多种请求方法。 HTTP1.0 定义了三种请求方法&#xff1a; GET, POST 和 HEAD 方法。 HTTP1.1 新增了六种请求方法&#xff1a;OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。 RequestMapping注解与其派生注解 在…

Qt实现动画的2种方式

由于我之前是写java的所以在学习Qt的时候感觉会有点熟悉&#xff0c;因为Qt就是 用c写&#xff0c;而java底层也是c实现的 先看效果&#xff1a; 一、使用QMovie 这种方式我目前是用来加载gif图的&#xff0c;很简单噢&#xff0c;只不过我是加载的本地的路径&#xff0c;如…

数据安全无阻,轻松远程工作!迅软DSE出差加密指南,让你出差更放心!

文件加密软件是确保内网文件安全使用的重要工具&#xff0c;但在终端脱离内部网络、面对外出或居家办公等情境时&#xff0c;文件加密的挑战也相应增加。为解决这一问题&#xff0c;迅软DSE文件加密软件提供了离线授权功能&#xff0c;确保在终端脱离公司网络后的设定时间内&am…

抖店怎么运营?新手运营方法,这几个流程告诉你!

我是电商珠珠 抖店的热度一直很高&#xff0c;很多新手在入驻抖店的时候&#xff0c;并不知道怎么去运营。 其实&#xff0c;从开店到店铺维护&#xff0c;这几个步骤你们一次就能看懂。 第一步&#xff0c;入驻 入驻的时候需要准备一张个体的营业执照、身份证、银行卡、手…

泽众一站式自动化测试平台TestOne,自动化测试的整体框架和功能介绍

TestOne是泽众软件自主研发的一体化测试系统&#xff0c;基于 B/S 体系的微服务架构&#xff0c;集系统管理、项目管理、测试管理、缺陷管理等功能于一体&#xff0c;覆盖了GUI界面功能自动化测试、接口自动化测试、移动自动化测试类型&#xff0c;完整覆盖自动化测试项目的全过…

LoadRunnder介绍

LoadRunner介绍安装教程LoadRunner三大组件 LoadRunner介绍 性能测试的定义&#xff1a;测试人员借助性能测试工具&#xff0c;模拟系统在不同场景下&#xff0c;对应的性能指标是否达到预期 定义中这个工具是什么呢&#xff1f; 可以使用LoadRunner测试 这个工具相比于其它工…

linux 内核同步互斥技术之每处理器变量

在多处理器系统中&#xff0c;每处理器变量为每个处理器生成一个变量的副本&#xff0c;每个处理器访问自己的副本&#xff0c;从而避免了处理器之间的互斥和处理器缓存之间的同步&#xff0c;提高了程序的执行速度。 每处理器变量分为静态和动态两种。 静态每处理器变量 使…

Flutter开发笔记 —— sqflite插件数据库应用

前言 今天在观阅掘金大佬文章的时候&#xff0c;了解到了该 sqflite 插件&#xff0c;结合官网教程和自己实践&#xff0c;由此总结出该文&#xff0c;希望对大家的学习有帮助&#xff01; 插件详情 Flutter的 SQLite 插件。支持 iOS、Android 和 MacOS。 支持事务和batch模式…

智能优化算法应用:基于入侵杂草算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于入侵杂草算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于入侵杂草算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.入侵杂草算法4.实验参数设定5.算法结果6.…

【LeetCode刷题笔记(8-3)】【Python】【接雨水】【双指针】【困难】

文章目录 引言接雨水题目描述提示 解决方案3&#xff1a;【双指针】结束语 接雨水 【LeetCode刷题笔记&#xff08;8-1&#xff09;】【Python】【接雨水】【动态规划】【困难】 【LeetCode刷题笔记&#xff08;8-2&#xff09;】【Python】【接雨水】【单调栈】【困难】 引言…

Arcgis新建矢量并手动绘制范围

新建一个shapefile&#xff0c;并选择面 得到了一个新shape 然后右击&#xff0c;开始编辑&#xff0c;打开编辑器

mysql 当前时间加3个工作日

1. 问题描述&#xff1a; 在日常工作中可能会遇到计算工作日的情况 2. 解决过程 (1) 首先制作一个假日表 holiday_config CREATE TABLE holiday_config (id int(10) NOT NULL AUTO_INCREMENT,holiday varchar(8) DEFAULT NULL,PRIMARY KEY (id) USING BTREE ) ENGINEInnoDB…

issue queue的实现方式

主要从一下几个点进行考虑&#xff1a; 集中式&#xff08;Centrallized&#xff09;或者分布式(Distributed)&#xff1b;压缩式&#xff08;Compressing&#xff09;或者非压缩式(Non-compressing)&#xff1b;数据捕捉的方式&#xff08;Data-capture&#xff09;或者非数据…

matlab中Signal Builder模块的用法总结

目录 前言方法一方法二参考文章 前言 今天在用matlab中Signal Builder的模块时&#xff0c;不知道怎么去得到想要的信号源&#xff0c;于是上网查了一下&#xff0c;并记录一下 方法一 如图所示&#xff0c;打开自定义 上面一行是横坐标&#xff0c;下面一行是纵坐标 [0,1…

什么是Symbol?在实际开发中怎么用?

Symbol 是 ECMAScript 6&#xff08;ES6&#xff09;引入的一种新的基本数据类型。Symbol 类型的值是唯一且不可变的。目的是确保对象属性使用唯一标识符&#xff0c;不会发生属性冲突的危险。 1. 使用Symbol() 创建 调用 Symbol()函数时&#xff0c;也可以传入一个字符串参数…

ubuntu docker镜像制作及常用命令

ubuntu docker镜像制作及常用命令 一、安装docker 1、安装 sudo apt install docker.io 2、拉取ubuntu镜像 sudo docker pull ubuntu:18.04 3、从Dockerfile构建镜像 3.1、 Dockerfile示例 FROM ubuntu:18.04MAINTAINER [user] [email]RUN apt-get update \&& …