JavaScript常用技巧专题五

文章目录

  • 一、使用适当的命名和注释来提高代码可读性
  • 二、优雅的写条件判断代码
    • 2.1、普通的`if else`
    • 2.2、三元运算符
    • 2.3、多个`if else`
    • 2.4、`switch case`
    • 2.5、对象写法
    • 2.6、`Map`写法
  • 三、封装条件语句
  • 四、函数应该只做一件事
  • 五、`Object.assign`给默认对象赋默认值
  • 六、函数参数两个以下最好
  • 七、使用解释性的变量
  • 八、让对象拥有私有成员-通过闭包来实现
  • 九、使用方法链
  • 十、最后

一、使用适当的命名和注释来提高代码可读性

// 不好的
const x = 10; // 设置x的值为10
function a(b) {
 return b * 2; // 返回b的两倍
}
// 好的
const speed = 10; // 设置速度为10
function double(value) {
 return value * 2; // 返回输入值的两倍
}

二、优雅的写条件判断代码

简单的条件判断逻辑用if else 或者 三元运算符, 一眼看过去还能知道说的啥,但是大量的if else和叠加在一起的三元运算符就是接盘侠的噩梦~~~

给大家上一个三元运算符叠加的案例,我是真实在项目中遇到过,cpu直接干爆~~~

<view>{{status===1?'成功': status===2 ? '失败' : status===3 ? '进行中' : '未开始' }}</view>

大概是这样的,具体的项目代码不好放在这里,小伙伴们意会就行。

复杂逻辑推荐使用对象Map写法,符合人脑的逻辑,可读性高,看着舒服~~~

2.1、普通的if else

let txt = '';
if (falg) {
 txt = "成功"
} else {
 txt = "失败"
}

2.2、三元运算符

let txt = flag ? "成功" : "失败";

2.3、多个if else

// param {status} status 活动状态:1:成功 2:失败 3:进行中 4:未开始
let txt = '';
if (status == 1) {
 txt = "成功";
} else if (status == 2) {
 txt = "失败";
} else if (status == 3) {
 txt = "进行中";
} else {
 txt = "未开始";
}

2.4、switch case

let txt = '';
switch (status) {
 case 1:
 txt = "成功";
 break;
 case 2:
 txt = "成功";
 break;
 case 3:
 txt = "进行中";
 break;
 default:
 txt = "未开始";
}

2.5、对象写法

const statusMap = {
 1: "成功",
 2: "失败",
 3: "进行中",
 4: "未开始"
}
//调用直接 statusMapp[status]

2.6、Map写法

const actions = new Map([
 [1, "成功"],
 [2, "失败"],
 [3, "进行中"],
 [4, "未开始"]
])
// 调用直接 actions.get(status)

三、封装条件语句

同上,if里的条件越多越不利于接盘侠的维护,不利于人脑的理解,一眼看过去又是一堆逻辑。多个逻辑应该化零为整

大脑:'别来碰我,让我静静'
// 不好的
if (fsm.state === 'fetching' && isEmpty(listNode)) {
 // ...
}
// 好的
shouldShowSpinner(fsm, listNode){
 return fsm.state === 'fetching' && isEmpty(listNode)
}
if(shouldShowSpinner(fsm, listNode)){
 //...doSomething
}

四、函数应该只做一件事

函数式写法推崇柯里化, 一个函数一个功能,可拆分可组装。

// 不好的
function createFile(name, temp) {
 if (temp) {
   fs.create(`./temp/${name}`);
 } else {
   fs.create(name);
 }
}
// 好的
function createFile(name) {
 fs.create(name);
}
function createTempFile(name) {
 createFile(`./temp/${name}`)
}

再来一个栗子

函数要做的事情如下:

  • 遍历clients数组
  • 遍历过程中,通过lookup函数得到一个新的对象clientRecord
  • 判断clientRecord对象中isActive函数返回的是不是true,
  • isActive函数返回true,执行email函数并把当前成员带过去
// 不好的
function emailClients(clients) {
 clients.forEach((client) => {
   const clientRecord = database.lookup(client);
   if (clientRecord.isActive()) {
     email(client);
   }
 });
}
// 好的
function emailClients(clients) {
 clients
   .filter(isClientRecord)
   .forEach(email)
}
function isClientRecord(client) {
 const clientRecord = database.lookup(client);
 return clientRecord.isActive()
}

上面不好的栗子一眼看过去是不是感觉一堆代码在那,一时半会甚至不想去看了。

好的栗子,是不是逻辑很清晰,易读。

  • 巧用filter函数,把filter的回调单开一个函数进行条件处理,返回符合条件的数据
  • 符合条件的数据再巧用forEach,执行email函数

五、Object.assign给默认对象赋默认值

// 不好的
const menuConfig = {
 title: null,
 body: 'Bar',
 buttonText: null,
 cancellable: true
};
function createMenu(config) {
 config.title = config.title || 'Foo';
 config.body = config.body || 'Bar';
 config.buttonText = config.buttonText || 'Baz';
 config.cancellable = config.cancellable === undefined ?
 config.cancellable : true;
}
createMenu(menuConfig);
// 好的
const menuConfig = {
 title: 'Order',
 buttonText: 'Send',
 cancellable: true
};
function createMenu(config) {
 Object.assign({
   title: 'Foo',
   body: 'Bar',
   buttonText: 'Baz',
   cancellable: true 
 }, config)
}
createMenu(menuConfig);

六、函数参数两个以下最好

说一千道一万,就是为了优雅,就是为了可读性好。

// 不好的
function createMenu(title, body, buttonText, cancellable) {
 // ...
}
// 好的
const menuConfig = {
 title: 'Foo',
 body: 'Bar',
 buttonText: 'Baz',
 cancellable: true
};
function createMenu(config){
 // ...
}
createMenu(menuConfig)

七、使用解释性的变量

省流,用了扩展运算符,为了可读性(saveCityZipCode(city, zipCode)可读性很好,知道参数是干嘛的)

// 不好的
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
saveCityZipCode(address.match(cityZipCodeRegex)[1], address.match(cityZipCodeRegex)[2]);
// 好的
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
cosnt [, city, zipCode] = address.match(cityZipCodeRegex) || [];
saveCityZipCode(city, zipCode)

想对类中的属性进行更多自定义取/增/改的操作时,使用set/get

第一次见这个写法,不知道是啥意思的小伙伴,把他当成vue2中的defineProperty

Object.defineProperty(data1,'age',{
 set:function(newAge){
   console.log(this.name+'现在'+newAge+'岁')
 },
 get:function(){
   return 18;
 }
})

是一个意思,赋值的时候set会被触发,取值的时候get会被触发。

巧用自带属性,提升性能。

class BankAccount {
 constructor(balance = 1000) {
   this._balance = balance;
 }
 // It doesn't have to be prefixed with `get` or `set` to be a
 //getter/setter
 set balance(amount) {
   console.log('set')
   if (verifyIfAmountCanBeSetted(amount)) {
     this._balance = amount;
   }
 }
 get balance() {
   console.log('get')
   return this._balance;
 }
 verifyIfAmountCanBeSetted(val) {
   // ...
 }
}
const bankAccount = new BankAccount();
// Buy shoes...
bankAccount.balance -= 100;
// Get balance
let balance = bankAccount.balance;

八、让对象拥有私有成员-通过闭包来实现

闭包天生就是做私有化的

// 不好的
const Employee = function(name) {
 this.name = name;
};
Employee.prototype.getName = function getName() {
 return this.name;
};
const employee = new Employee('John Doe');
console.log(`Employee name: ${employee.getName()}`); // Employee name: John Doe
delete employee.name;
console.log(`Employee name: ${employee.getName()}`); // Employee name: undefined
// 好的
const Employee = function(name){
 this.getName = function(){
   return name
 }
}
const employee = new Employee('John Doe');
console.log(`Employee name: ${employee.getName()}`); // Employee name: John Doe
delete employee.name;
console.log(`Employee name: ${employee.getName()}`); // Employee name: undefined

第一个示例

优点:

  • 通过原型链共享方法,节省了内存空间。所有实例对象共享同一个 getName 方法,而不是每个实例对象都创建一个独立的方法。

缺点:

  • 在构造函数中无法直接定义私有属性或方法,所有属性和方法都会被暴露在原型链上

第二个示例

优点:

  • 可以在构造函数内部定义私有属性和方法,不会暴露在对象的原型链上,提供了更好的封装性。

缺点:

  • 每次创建实例对象时,都会创建一个独立的方法,每个实例对象都有自己的 getName 方法,占用更多的内存空间。

九、使用方法链

链式写法也是代码优雅之道的重头戏。

ps:发明这个的程序员肯定是后端出身的,这种写法在PHPCI框架中见过。

// 不好的
class Car {
 constructor() {
   this.make = 'Honda';
   this.model = 'Accord';
   this.color = 'white';
 }
 setMake(make) {
   this.make = make;
 }
 save() {
   console.log(this.make, this.model, this.color);
 }
}
const car = new Car();
car.setMake('Ford');
car.save();
// 好的
class Car {
 constructor() {
   this.make = 'Honda';
   this.model = 'Accord';
   this.color = 'white';
 }
 setMake(make) {
   this.make = make;
   // NOTE: return this是为了用链式写法
   return this;
 }
 save() {
   console.log(this.make, this.model, this.color);
   // NOTE:return this是为了用链式写法
   return this;
 }
}
const car = new Car()
 .setMake('Ford')
 .save();

十、最后

本人每篇文章都是一字一句码出来,希望对大家有所帮助,多提提意见。顺手来个三连击,点赞👍收藏💖关注✨,一起加油☕

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OpenGL 绘制Mesh数据(Qt)

文章目录 一、简介二、实现代码三、实现效果一、简介 Mesh数据的结构主要就是点与三角面片,因此本质上仍然是对三角面片进行绘制。这里我们借助VCG这个库实现对Mesh数据的读取,这个库相对简单轻巧,很方便使用。 二、实现代码 由于修改的部分很多,我们逐一进行解释一下: --…

云服务器安装Docker并启动相关服务

云服务器安装Docker 环境准备1、云服务器2、在windterm创建会话2.1、登录2.2、身份验证失败的解决方案在创建好终端服务器修改密码修改会话设置取消不必要的验证 2.3生成密钥流程 3、安装docker3.1 安装报错3.2 解决方案3.2.1操作步骤3.2.1.1 查看当前目录下有那些文件3.2.1.2跳…

智能算法(GA、DBO等)求解零空闲流水车间调度问题(NIFSP)

先做一个声明&#xff1a;文章是由我的个人公众号中的推送直接复制粘贴而来&#xff0c;因此对智能优化算法感兴趣的朋友&#xff0c;可关注我的个人公众号&#xff1a;启发式算法讨论。我会不定期在公众号里分享不同的智能优化算法&#xff0c;经典的&#xff0c;或者是近几年…

6G未来的潜在应用场景

虽然目前6G还不是一种可行技术&#xff0c;但是离6G技术成熟和普及的时间应该不远了。未来6G一旦普及&#xff0c;将能够支持全球更大的设备网络&#xff0c;彻底改变医疗保健等行业的应用&#xff0c;并将有助于更多技术的开发和普及。 虽然过渡到6G技术需要时间&#xff0c;…

【C++11/17】std::map高效插入

我们在使用stl的映射容器std::map时&#xff0c;经常需要向容器中插入数据。由于map的元素key值是唯一的&#xff0c;我们经常遇到这样的场景&#xff1a; 向map中插入元素时&#xff0c;指定的key已经存在则直接更新&#xff1b;指定的key不存在&#xff0c;然后才做插入操作…

解读SPP / SPPF / SimSPPF / ASPP / RFB / SPPCSPC

SPP与SPPF 一、SPP的应用的背景 在卷积神经网络中我们经常看到固定输入的设计&#xff0c;但是如果我们输入的不能是固定尺寸的该怎么办呢&#xff1f; 通常来说&#xff0c;我们有以下几种方法&#xff1a; &#xff08;1&#xff09;对输入进行resize操作&#xff0c;让他们…

Netty-4-网络编程模式

我们经常听到各种各样的概念——阻塞、非阻塞、同步、异步&#xff0c;这些概念都与我们采用的网络编程模式有关。 例如&#xff0c;如果采用BIO网络编程模式&#xff0c;那么程序就具有阻塞、同步等特质。 诸如此类&#xff0c;不同的网络编程模式具有不同的特点&#xff0c…

linux循环调度执行

9.2 循环调度执行 9.2.1 简介 cron的概念和crontab是不可分割的。 ​ crontab是一个命令&#xff0c;常见于Unix和Linux的操作系统之中用于设置周期性被执行的指令。 ​ 该命令从标准输入设备读取指令&#xff0c;并将其存放于“crontab”文件中&#xff0c;以供之后读取和执…

文章标题(备注)

现在也裁员了吗&#xff1f;怎么感觉越来越垃圾 这个又是什么&#xff1f;真搞笑&#xff0c;我也没开隐私呀

Linux:jumpserver介绍(1)

官方网站 JumpServer - 开源堡垒机 - 官网https://www.jumpserver.org/ JumpServer 是广受欢迎的开源堡垒机&#xff0c;是符合 4A 规范的专业运维安全审计系统。JumpServer 帮助企业以更安全的方式管控和登录所有类型的资产&#xff0c;实现事前授权、事中监察、事后审计&…

本地搜索文件太慢怎么办?用Everything搜索秒出结果(附安装包)

每次用电脑本地的搜索都慢的一批&#xff0c;后来发现了一个搜索利器 基本上搜索任何文件都不用等待。 并且页面非常简洁&#xff0c;也没有任何广告&#xff0c;用起来非常舒服。 软件官网如下&#xff1a; voidtools 官网提供三个版本&#xff0c;用起来差别不大。 网盘链…

复分析——第1章——复分析准备知识(E.M. Stein R. Shakarchi)

第一章 复分析准备知识 (Preliminaries to Complex Analysis) The sweeping development of mathematics during the last two centuries is due in large part to the introduction of complex numbers; paradoxically, this is based on the seemingly absurd no…

Shell三剑客:awk(awk编辑编程)一

一、awk脚本定义格式 格式1&#xff1a; BEGIN{} pattern{} END{}格式2&#xff1a; #!/bin/awk -f #add x right BEGIN{} pattern{} END{} BEGIN{ 这里面放的是执行前的语句 }END {这里面放的是处理完所有的行后要执行的语句 }{这里面放的是处理每一行时要执行的语句}格式1假…

整数规划-割平面法

整数规划-割平面法 割平面法思想Gomorys割平面法原理实例 谨以此博客作为学习期间的记录。 割平面法思想 在之前&#xff0c;梳理了分支定界法的流程:分支定界法 除了分支定界法&#xff0c;割平面法也是求解整数规划的另一个利器。 我们已经知道&#xff0c;线性规划的可行域…

智能优化算法应用:基于广义正态分布算法3D无线传感器网络(WSN)覆盖优化 - 附代码

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

Grafana二进制部署并配置prometheus数据源

1、获取grafna二进制安装包 https://grafana.com/grafana/download?pggraf&plcmtdeploy-box-1 grafana官网下载地址 [rootambari-hadoop1 ~]# cd /opt/module/grafana/ [rootambari-hadoop1 grafana]# pwd /opt/module/grafana2、在安装自己的安装目录执行 wget https:…

国漫风向标!2023年玄机科技斩获6项腾讯金鹅荣誉

12月16日&#xff0c;2023腾讯视频金鹅荣誉发布&#xff0c;玄机科技凭借其卓越的制作实力和市场认可度&#xff0c;斩获了6项大奖&#xff01;这一荣誉的背后&#xff0c;是玄机科技无数次的创新与突破&#xff0c;也是对其不懈努力的肯定与鼓励。 玄机科技一直以其精良的制作…

半导体晶圆制造SAP:助力推动新时代科技创新

随着科技的迅猛发展&#xff0c;半导体行业成为了推动各行各业进步的重要力量。而半导体晶圆制造作为半导体产业链的核心环节&#xff0c;其效率和质量的提升对于整个行业的发展起着决定性的作用。在这个高度竞争的行业中&#xff0c;如何提升制造过程的效率、降低成本&#xf…

显示器屏幕oled的性能、使用场景、维护

OLED显示器屏幕具有许多独特的性能和使用场景&#xff0c;以下是关于OLED显示器屏幕的性能、使用场景和维护的详细介绍&#xff1a; 一、性能 色彩鲜艳&#xff1a;OLED显示器屏幕能够呈现出更加鲜艳的色彩&#xff0c;色彩饱和度高&#xff0c;色彩还原性好&#xff0c;可以给…

Linux命令指南

Linux上显示某个进程的线程方式 方法一&#xff1a;PS 在ps命令中&#xff0c;“-T”选项可以开启线程查看。下面的命令列出了由进程号为的进程创建的所有线程。 ps -T -p <pid>“SPID”栏表示线程ID&#xff0c;而“CMD”栏则显示了线程名称。 方法二&#xff1a; T…