20个提升效率的JS简写技巧,告别屎山!
JavaScript 中有很多简写技巧,可以缩短代码长度、减少冗余,并且提高代码的可读性和可维护性。本文将介绍 20 个提升效率的 JS 简写技巧,助你告别屎山,轻松编写优雅的代码!
移除数组假值
可以使用 filter() 结合 Boolean 来简化移除数组假值操作。假值指的是在条件判断中被视为 false 的值,例如 null、undefined、空字符串("" 或 '')、0、NaN 和 false。
传统写法:
let arr = [12, null, 0, 'xyz', null, -25, NaN, '', undefined, 0.5, false];let filterArray = arr.filter(value => {if(value) {return value};}); // [12, 'xyz', -25, 0.5]
简化写法:
let arr = [12, null, 0, 'xyz', null, -25, NaN, '', undefined, 0.5, false];let filterArray = arr.filter(value => Boolean(value)); // [12, 'xyz', -25, 0.5]
更简化写法:
let arr = [12, null, 0, 'xyz', null, -25, NaN, '', undefined, 0.5, false];let filterArray = arr.filter(Boolean); // [12, 'xyz', -25, 0.5]
Boolean 是 JavaScript 的内置构造函数,通过传递一个值给它,可以将该值转换为布尔值。在这种情况下,Boolean 构造函数作为回调函数传递给 filter() 方法,因此会将每个数组元素转换为布尔值。只有转换结果为真值的元素才会保留在新数组中。
注意:这种方式会将 0 也过滤掉,如果不需要过滤 0,需要进行额外的判断。
数组查找
当对数组进行查找时,indexOf()用于获取查找项的位置。如果未找到该项,则返回值为-1。在JavaScript中,0被视为false,而大于或小于0的数字被视为true。因此,需要这样来写:
传统写法:
if(arr.indexOf(item) > -1) { }if(arr.indexOf(item) === -1) {}
简化写法:
if(~arr.indexOf(item)) {}if(!~arr.indexOf(item)) {}
位非()运算符对除了-1之外的任何值都返回一个"真"值。对其进行取反就是简单地使用`!即可。另外,也可以使用includes()`函数:
if(arr.includes(item)) {}
空值合并运算符
空值合并运算符(??)用于为 null 或 undefined 的变量提供默认值。
传统写法:
const fetchUserData = () => {return '前端充电宝';};const data = fetchUserData();const username = data !== null && data !== undefined ? data : 'Guest';
简化写法:
const fetchUserData = () => {return '前端充电宝';};const data = fetchUserData();const username = data ?? 'CUGGZ';
除此之外,还有一个空位合并赋值运算符(??=),用于在变量为空(null 或 undefined)时进行赋值操作。
传统写法:
let variable1 = null;let variable2 = "前端充电宝";if (variable1 === null || variable1 === undefined) {variable1 = variable2;}
简化写法:
let variable1 = null;let variable2 = "前端充电宝";variable1 ??= variable2;
??= 的写法更加简洁和易读。它首先检查变量 variable1 是否为 null 或 undefined,如果是,则将它赋值为 variable2 的值。如果 variable1 已经有一个非空的值,那么赋值操作就不会发生。
逻辑或赋值运算符
逻辑或赋值运算符(||=)用于为变量分配默认值。
传统写法:
let count;if (!count) {count = 0;}
简化写法:
let count;count ||= 0;
当 count 为假值(例如 undefined、null、false、0、NaN 或空字符串)时,逻辑或赋值运算符将 count 赋值为 0。否则,它会保留 count 的原始值。
多值匹配
对于多个值的匹配,可以将所有的值放入一个数组中,然后使用 indexOf() 方法进行检查。indexOf() 方法是 JavaScript 数组的一个内置方法,它用于返回指定元素在数组中第一次出现的位置索引。如果数组中不存在该元素,则返回 -1。
传统写法:
if (value === 1 || value === 'one' || value === 2 || value === 'two') {// ...}
简化写法:
if ([1, 'one', 2, 'two'].indexOf(value) >= 0) {// ...}
更简化写法:
if ([1, 'one', 2, 'two'].includes(value)) { // ...}
三元表达式
使用三元表达式表示可以简化if...else。
传统写法:
let isAdmin;if (user.role === 'admin') {isAdmin = true;} else {isAdmin = false;}
简化写法:
const isAdmin = user.role === 'admin' ? true : false;
更简化写法:
const isAdmin = user.role === 'admin';
短路求值
当将一个变量的值赋给另一个变量时,可能希望确保源变量不为 null、undefined 或空。可以编写一个包含多个条件的长 if 语句,或者使用短路求值来简化。
if (variable1 !== null || variable1 !== undefined || variable1 !== '') {let variable2 = variable1;}
使用短路求值简化后的代码如下:
const variable2 = variable1 || 'new';
对于逻辑或(||)操作符,以下值被视为假:
false
0
空字符串("" 或 '')
null
undefined
NaN
所以,如果本身的值可能就是这些中的一个,就不适合使用短路求值。
短路求值还能在函数调用中避免不必要的函数执行。
传统写法:
function fetchData() {if (shouldFetchData) {return fetchDataFromAPI();} else {return null;}}
简化写法:
function fetchData() {return shouldFetchData && fetchDataFromAPI();}
当 shouldFetchData 为真值时,短路求值会继续执行 fetchDataFromAPI() 函数并返回其结果。如果 shouldFetchData 为假值,短路求值会直接返回假值(null),避免了不必要的函数调用。
科学计数法
可以使用科学技术法来表示数字,以省略尾部的零。例如,1e7 实际上表示 1 后面跟着 7 个零。它表示一个十进制,相当于 10,000,000。
传统写法:
for (let i = 0; i < 10000; i++) {}
简化写法:
for (let i = 0; i < 1e7; i++) {}// 下面的所有比较都将返回 true1e0 === 1;1e1 === 10;1e2 === 100;1e3 === 1000;1e4 === 10000;1e5 === 100000;
位运算符
双位非运算符有一个非常实用的用途,可以用它来替代Math.floor()函数,它在执行相同的操作时速度更快。
传统写法:
Math.floor(4.9) === 4 //true
简化写法:
~~4.9 === 4 //true
指数幂运算
指数幂运算可以使用 ** 来简化。
传统写法:
Math.pow(2,3); // 8Math.pow(2,2); // 4Math.pow(4,3); // 64
简化写法:
2**3 // 82**4 // 44**3 // 64
从 ES7(ECMAScript 2016)开始,JavaScript 引入了指数幂运算符 **,使指数幂运算更加简洁。
双非未运算符
在 JavaScript 中,双非位运算符 ~~ 可以用于将数字向下取整,类似于 Math.floor() 方法的功能。
传统写法:
const floor = Math.floor(6.8); // 6
简化写法:
const floor = ~~6.8; // 6
注意:双非位运算符只适用于 32 位整数,即范围为 -(2^31) 到 (2^31)-1,即 -2147483648 到 2147483647。对于大于 2147483647 或小于 0 的数字,双非位运算符(~~)会给出错误的结果,因此建议在这种情况下使用 Math.floor() 方法。
对象属性
ES6 提供了一种更简洁的方式来给对象赋值属性。如果变量名与对象的键名相同,可以利用简写符号来进行赋值。
传统写法:
const name = '微信公众号:前端充电宝';const age = 18;const person = {name: name,age: age};
简化写法:
const name = '微信公众号:前端充电宝';const age = 30;const person = {name,age};
箭头函数
箭头函数可以简化经典函数的写法。
传统写法:
function sayHello(name) {console.log('Hello', name);}setTimeout(function() {console.log('Loaded')}, 2000);list.forEach(function(item) {console.log(item);});
简化写法:
sayHello = name => console.log('Hello', name);setTimeout(() => console.log('Loaded'), 2000);list.forEach(item => console.log(item));
如果箭头函数只有一条语句,它会隐式地返回其求值的结果,这时可以省略 return 关键字:
传统写法:
function calcCircumference(diameter) {return Math.PI * diameter}
简化写法:
calcCircumference = diameter => (Math.PI * diameter;)
参数解构
如果正在使用一些流行的 Web 框架,比如 React、Vue,可能会使用数组或对象字面量形式的数据来在组件之间传递信息。在组件中要想使用数据对象,就需要对其进行解构。
传统写法:
const observable = require('mobx/observable');const action = require('mobx/action');const runInAction = require('mobx/runInAction');const store = this.props.store;const form = this.props.form;const loading = this.props.loading;const errors = this.props.errors;const entity = this.props.entity;
简化写法:
import { observable, action, runInAction } from 'mobx';const { store, form, loading, errors, entity } = this.props;
还可以为变量赋予新的变量名:
const { store, form, loading, errors, entity:contact } = this.props;
扩展运算符
在ES6中引入的扩展运算符可以简化数组和对象的一些操作。
传统写法:
// 合并数组const odd = [1, 3, 5];const nums = [2, 4, 6].concat(odd);// 克隆数组const arr = [1, 2, 3, 4];const arr2 = arr.slice();
简化写法:
// 合并数组const odd = [1, 3, 5];const nums = [2, 4, 6, ...odd];console.log(nums); // [ 2, 4, 6, 1, 3, 5 ]// 克隆数组const arr = [1, 2, 3, 4];const arr2 = [...arr];
与 concat() 函数不同,可以使用扩展运算符在另一个数组的任意位置插入一个数组。
const odd = [1, 3, 5];const nums = [2, ...odd, 4, 6];
还可以将扩展运算符与ES6的解构语法结合使用:
const { a, b, ...z } = { a: 1, b: 2, c: 3, d: 4 };console.log(a) // 1console.log(b) // 2console.log(z) // { c: 3, d: 4 }
扩展运算符还能用于合并对象:
传统写法:
let fname = { firstName : '前端' };let lname = { lastName : '充电宝'}let full_names = Object.assign(fname, lname);
简化写法:
let full_names = {...fname, ...lname};
强制参数
在传统的 JavaScript 写法中,为了确保函数参数被传入一个有效值,我们需要使用条件语句来抛出一个错误。可以通过使用强制参数简写的写法实现相同的逻辑。
传统写法:
function foo(bar) {if(bar === undefined) {throw new Error('Missing parameter!');}return bar;}
简化写法:
mandatory = () => {throw new Error('Missing parameter!');}foo = (bar = mandatory()) => {return bar;}
这里定义了一个名为 mandatory 的函数,用于抛出一个错误,表示函数参数未被传入。然后,在函数 foo 的参数列表中,使用赋默认值的方式来将 bar 参数设置为 mandatory() 的调用结果,如果 bar 参数未被传入或者传入了假值,就会触发 mandatory() 函数的执行。
转为布尔值
可以使用双重逻辑非操作符将任何值转换为布尔值。
!!23 // TRUE!!"" // FALSE!!0 // FALSE!!{} // TRUE
单一的逻辑非操作符已经可以将值转换为布尔类型并对其进行取反,所以第二个逻辑非操作符会再次对其进行取反,从而将其恢复为原始含义,并保持为布尔类型。
变量交换
可以使用数组解构来轻松实现变量交换。
传统写法(使用临时变量完成两个变量的交换):
let a = 5;let b = 10;const temp = a;a = b;b = temp;
简化写法(使用数组解构赋值完成两个变量交换):
let a = 5;let b = 10;[a, b] = [b, a];
这里创建了一个包含两个元素的数组 [b, a],然后使用数组解构赋值将其中的值分别赋给变量 a 和 b。由于左侧的数组和右侧的数组结构相同,所以两个值会进行交换。
变量声明
当需要同时声明多个变量时,可以使用变量声明的简写方法来节省时间和空间。
传统写法:
let x;let y;let z = 3;
简化写法:
let x, y, z = 3;
不过,这个优化有些争议,很多人认为这么写会影响代码的可读性,因为许多变量写到了一行,不如一个变量一行更清晰明了,所以可以选择性采用。
如果有多个变量需要赋相同的值,则可以使用连等来实现。
传统写法:
let a = 100;let b = 100;let c = 100;
简化写法:
let a = b = c = 100;
For 循环
JavaScript 中传统的 for 循环语法使用数组的长度作为迭代器来遍历数组。还有很多 for 循环的快捷方式提供了在数组中迭代对象的不同方法,例如:
for...of:用于遍历内置字符串、数组、类数组对象、NodeList。for...in:用于访问数组的索引和对对象字面量进行遍历,并记录属性名称和值的字符串。Array.forEach:使用回调函数对数组元素及其索引执行操作。
传统写法:
for (let i = 0; i < arr.length; i++) {console.log("item: ", arr[i]);}}
简化写法:
for (let str of arr) {console.log("item: ", str);}arr.forEach((str) => {console.log("item: ", str);});for (let index in arr) {console.log(index, arr[index]);}
对于对象字面量,也可以使用 for...in 来遍历:
const obj = { a: 1, b: 3, c: 5 };for (let key in obj) {console.log(key, obj[key]);}
往期推荐
VS Code 中使用Git实践,学会了效率翻倍!
微软最热门的10款前端开源项目!
JavaScript 终于原生支持数组分组了!
Next.js 13.5 正式发布,速度大幅提升!
多图预警,前端应该掌握的浏览器调试技巧大揭秘!
竟然可以在一个项目中混用 Vue 和 React?
图解 60 个 CSS 选择器,一网打尽! 
相关文章:
20个提升效率的JS简写技巧,告别屎山!
JavaScript 中有很多简写技巧,可以缩短代码长度、减少冗余,并且提高代码的可读性和可维护性。本文将介绍 20 个提升效率的 JS 简写技巧,助你告别屎山,轻松编写优雅的代码! 移除数组假值 可以使用 filter() 结合 Bool…...
Pikachu靶场——SSRF 服务端请求伪造
文章目录 1 SSRF 服务端请求伪造1.1 SSRF(curl)1.1.1 漏洞防御 1.2 SSRF(file_get_content)1.2.1 漏洞防御1.2.3 SSRF 防御 1 SSRF 服务端请求伪造 SSRF(Server-Side Request Forgery:服务器端请求伪造) 其形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能&a…...
Android file
写文件——FileOutputStream openFileOutput 读文件——FileInputStream openFileInput openFileOutput写文件时当文件不存在,Android自动创建。 通过BufferedWriter直接写入字符串 public void writeFile(String inputText) {FileOutputStream outputStream nul…...
【计算机网络】计网常见面试题总结
目录 一、谈一谈对OSI七层模型和TCP/IP四层模型的理解? 二、谈一谈TCP协议的三次握手过程? 三、TCP协议为什么要三次握手?两次、四次不行吗? 四、谈一谈TCP协议的四次挥手过程? 五、什么是流量控制? …...
SpringMVC 学习(七)JSON
9. JSON 9.1 简介 JSON(JavaScript Object Notation,JS 对象标记)是一种轻量级数据交换格式,采用独立于编程语言的文本格式储存和表示数据,易于机器解析和生成,提升网络传输效率。 任何 JavaScript 支持…...
重学C++ | std::set 的原理
std::set 是C标准库中的容器之一,它基于红黑树实现。std::set 利用红黑树的特性来实现有序的插入、查找和删除操作,并且具有较好的平均和最坏情况下的时间复杂度。 当向 std::set 插入元素时,它会按照特定的比较函数(bool less<…...
AnV-X6使用及总结
目录 1 简介2 安装3 基础概念3.1 画布Graph3.2 基类Cell3.3 节点Node3.4 边Edge 4 使用4.1 创建节点4.2 节点连线4.3 事件系统 5 总结 1 简介 AntV是一个数据可视化(https://x6.antv.antgroup.com/)的工具(https://antv.vision/zh/ …...
Go 围炉札记
文章目录 一、安装二、文档三、使用 一、安装 VSCode 和 CLion 为 Go 开发配置Visual Studio Code | Microsoft Learn VScode下配置Go语言开发环境【2023最新】 基础篇:新手使用vs code新建go项目 vscode里安装Go插件和配置Go环境 GO 笔记 Golang 配置代理 golang…...
数据分析回头看2——重复值检查/元素替换/异常值筛选
0、前言: 这部分内容是对Pandas的回顾,同时也是对Pandas处理异常数据的一些技巧的总结,不一定全面,只是自己在数据处理当中遇到的问题进行的总结。 1、当数据中有重复行的时候需要检测重复行: 方法:使用p…...
什么是OSPF?为什么需要OSPF
【微|信|公|众|号:厦门微思网络】 【微思网络www.xmws.cn,成立于2002年,专业培训21年,思科、华为、红帽、ORACLE、VMware等厂商认证及考试,以及其他认证PMP、CISP、ITIL等】 什么是OSPF? 开放式最短路径优…...
轻量级的日志采集组件 Filebeat 讲解与实战操作
文章目录 一、概述二、Kafka 安装三、Filebeat 安装1)下载 Filebeat2)Filebeat 配置参数讲解3)filebeat.prospectors 推送kafka完整配置1、filebeat.prospectors2、processors3、output.kafka 4)filebeat.inputs 与 filebeat.pros…...
C# 委托和事件
C# 委托和事件 委托匿名方法事件 委托 当要把方法传送给其他方法时,需要使用委托。首先定义要使用的委托,对于委托,定义它就是告诉编译器这种类型的委托代表了哪种类型的方法,然后创建该委托的一个或多个实例。编译器在后台将创建…...
数据结构与算法之字典: Leetcode 349. 两个数组的交集 (Typescript版)
两个数组的交集 https://leetcode.cn/problems/intersection-of-two-arrays/description/ 题目和解题参考 https://blog.csdn.net/Tyro_java/article/details/133279737 使用字典来解题的算法实现 字典:顾名思义,像新华字典一样可查找,基…...
day-56 代码随想录算法训练营(19)动态规划 part 16
538.两个字符串的删除操作 思路一: 1.dp存储:以word1[i-1]结尾,word2[j-1]结尾,最少进行dp[i][j]次操作2.动态转移方程: if(word1[i-1]word2[i-1]) dp[i][j]dp[i-1][j-1]; else dp[i][j]min(dp[i-1][…...
蓝桥等考Python组别四级005
第一部分:选择题 1、Python L4 (15分) 字符“0”的ASCII码值为48,则字符“5”的ASCII码值为( )。 3953120240正确答案:B 2、Python L4 (15分) 下面哪个是Python中正确的变量名?( ) ABC#sup01Trueif正确答案:B...
【Linux】diff 命令
【Linux】diff 命令——并排格式输出 功能 diff 以逐行的方式,比较文本文件的异同处。 如果指定要比较目录,则 diff 会比较目录中相同文件名的文件,但不会比较其中子目录 diff [参数] [文件A] [文件B]diff [参数] [目录A] [目录B]【参数】…...
【51单片机】9-定时器和计数器
1.定时器的介绍 1.什么是定时器 (1)SoC的一种内部的外设【在单片机里面,但是在CPU外面】 (2)定时器就是CPU的”闹钟“ 2.什么是计数器 (1)定时器就是用计数的原始实现的 (2…...
2023年海南省职业院校技能大赛(高职组)信息安全管理与评估赛项规程
2023年海南省职业院校技能大赛(高职组) 信息安全管理与评估赛项规程 一、赛项名称 赛项名称:信息安全管理与评估 英文名称:Information Security Management and Evaluation 赛项组别:高等职业教育 赛项归属产业&…...
大模型深挖数据要素价值:算法、算力之后,存储载体价值凸显
文 | 智能相对论 作者 | 叶远风 18.8万亿美元,这是市场预计2030年AI推动智能经济可产生的价值总和,其中大模型带来的AI能力质变无疑成为重要的推动力量。 大模型浪潮下,业界对AI发展的三驾马车——算力、算法、数据任何一个维度的关注都到…...
AI文章,AI文章生成工具
在互联网时代,随着信息爆炸式增长,文章的需求愈发旺盛。从博客、新闻、社交媒体到企业宣传,文字作为传达信息、吸引受众的工具变得愈发重要。但问题是,对于很多人来说,创作一篇高质量的文章并不容易。时间、创意、写作…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
