如何在JavaScript中正确处理变量


Posted in Javascript onDecember 25, 2020

变量无处不在。即便我们写一个小函数或一个小工具,也要声明、赋值和读取变量。增强对变量的重视,可以提高代码的可读性和可维护性。

1.建议使用 const,要么使用 let

用 const 或 let 声明自己的 JavaScript 变量。两者之间的主要区别是 const 变量在声明时需要初始化,并且一旦初始化就无法再重新赋值。

// const 需要初始化
const pi = 3.14;
// const 不能被重新赋值
pi = 4.89; 
// throws "TypeError: Assignment to constant variable"

let 声明不需要对值初始化,可以多次重新赋值。

// let 要不要初始化随你
let result;
// let 可被重新赋值
result = 14;
result = result * 2;

const 是一次性分配变量。因为你知道 const 变量不会被修改,所以与 let 相比,对 const 变量的推测比较容易。

声明变量时优先使用 const,然后是 let 。

假设你正在 review 一个函数,并看到一个 const result = ... 声明:

function myBigFunction(param1, param2) {
 /* 一写代码... */

 const result = otherFunction(param1);
 /* 一些代码... */
 return something;
}

虽然不知道 myBigFunction() 中做了些什么,但是我们可以得出结论,result 变量是只读的。

在其他情况下,如果必须在代码执行过程中多次重新对变量赋值,那就用 let。

2. 使变量的作用域最小化

变量位于创建它的作用域中。代码块和函数体为 const 和 let 变量创建作用域。

把变量保持在最小作用域中是提高可读性的一个好习惯。

例如下面的二分查找算法的实现:

function binarySearch(array, search) {
 let middle; let middleItem; let left = 0;
 let right = array.length - 1;

 while(left <= right) {
  middle = Math.floor((left + right) / 2);  
  middleItem = array[middle];  
  if (middleItem === search) { 
   return true; 
  }
  if (middleItem < search) { 
   left = middle + 1; 
  } else {
   right = middle - 1; 
  }
 }
 return false;
}

binarySearch([2, 5, 7, 9], 7); // => true
binarySearch([2, 5, 7, 9], 1); // => false

变量 middle 和 middleItem 是在函数的开头声明的,所以这些变量在 binarySearch() 函数的整个作用域内可用。变量 middle 用来保存二叉搜索的中间索引,而变量 middleItem 保存中间的搜索项。

但是 middle 和 middleItem 变量只用在 while 循环中。那为什么不直接在 while 代码块中声明这些变量呢?

function binarySearch(array, search) {
 let left = 0;
 let right = array.length - 1;

 while(left <= right) {
  const middle = Math.floor((left + right) / 2);  
   const middleItem = array[middle];  
   if (middleItem === search) {
    return true; 
  }
  if (middleItem < search) {
   left = middle + 1; 
  } else {
   right = middle - 1; 
  }
 }
 return false;
}

现在 middle 和 middleItem 只存在于使用变量的作用域内。他们的生命周期极短,所以更容易推断它们的用途。

3. 易于使用

我总是习惯于在函数开始的时候去声明所有变量,尤其是在写一些比较大的函数时。但是这样做会使我在函数中使用变量的意图变得非常混乱。

所以应该在变量声明时应该尽可能靠的近使用位置。这样你就不必去猜:哦,这里声明了变量,但是…它被用在什么地方呢?

假设有一个函数,在函数有包含很多语句。你可以在函数的开头声明并初始化变量 result,但是只在 return 语句中使用了 result:

function myBigFunction(param1, param2) {
 const result = otherFunction(param1); 
 let something;

 /*
  * 一些代码...
  */

 return something + result;}

问题在于 result 变量在开头声明,却只在结尾用到。我们并没有充分的理由在开始的时后就声明这个变量。

所以为了更好地理解 result 变量的功能和作用,要始终使变量声明尽可能的靠近使用它位置。

如果把代码改成这样:

function myBigFunction(param1, param2) {
 let something;

 /* 
  * 一些代码... 
  */

 const result = otherFunction(param1); 
 return something + result;}

现在是不是就清晰多了。

4. 合理的命名

你可能已经知道了很多关于变量命名的知识,所以在这里不会展开说明。不过在众多的命名规则中,我总结出了两个重要的原则:

第一个很简单:使用驼峰命名法,并终如一地保持这种风格。

const message = 'Hello';
const isLoading = true;
let count;

这个规则的一个例外是一些特定的值:比如数字或具有特殊含义的字符串。包特定值的变量通常用大写加下划线的形式,与常规变量区分开:

const SECONDS_IN_MINUTE = 60;
const GRAPHQL_URI = 'http://site.com/graphql';

我认为第二条是:变量名称应该清楚无误地表明是用来保存哪些数据的。

下面是一些很好的例子:

let message = 'Hello';
let isLoading = true;
let count;

message 名称表示此变量包含某种消息,很可能是字符串。

isLoading 也一样,是一个布尔值,用来指示是否正在进行加载。

毫无疑问,count 变量表示一个数字类型的变量,其中包含一些计数结果。

一定要选一个能够清楚表明其作用的变量名。

看一个例子,假设你看到了下面这样的代码:

function salary(ws, r) {
 let t = 0;
 for (w of ws) {
  t += w * r;
 }
 return t;
}

你能很容易知道函数的作用吗?与薪水的计算有关?非常不幸,我们很难看出 ws、 r、 t、 w这些变量名的作用。

但是如果代码是这样:

function calculateTotalSalary(weeksHours, ratePerHour) {
 let totalSalary = 0;
 for (const weekHours of weeksHours) {
  const weeklySalary = weekHours * ratePerHour;
  totalSalary += weeklySalary;
 }
 return totalSalary;
}

我们就很容易知道它们的作用,这就是合理命名的力量。

5.采用中间变量

我一般尽可能避免写注释,更喜欢写出能够自我描述的代码,通过对变量、属性、函数、类等进行合理的命名来表达代码的意图。

如果想使代码本身称为文档,一个好习惯是引入中间变量,这在在处理长表达式时很好用。

比如下面的表达式:

const sum = val1 * val2 + val3 / val4;

可以通过引入两个中间变量来提高长表达式的可读性:

const multiplication = val1 * val2;
const division    = val3 / val4;

const sum = multiplication + division;

再回顾一下前面的二叉搜索算法实现:

function binarySearch(array, search) {
 let left = 0;
 let right = array.length - 1;

 while(left <= right) {
  const middle = Math.floor((left + right) / 2);
  const middleItem = array[middle];  
  if (middleItem === search) {   
   return true; 
  }
  if (middleItem < search) {   
   left = middle + 1; 
  } else {
   right = middle - 1; 
  }
 }
 return false;
}

里面的 middleItem 就是一个中间变量,用于保存中间项。使用中间变量 middleItem 比直接用 array[middle] 更容易。

与缺少 middleItem 变量的函数版本进行比较:

function binarySearch(array, search) {
 let left = 0;
 let right = array.length - 1;

 while(left <= right) {
  const middle = Math.floor((left + right) / 2);
  if (array[middle] === search) {   
   return true; 
  }
  if (array[middle] < search) {   
   left = middle + 1; 
  } else {
   right = middle - 1; 
  }
 }
 return false;
}

没有中间变量的解释,这个版本稍微不太好理解。

通过使用中间变量用代码解释代码。中间变量可能会增加一些语句,但出于增强代码可读性的目的还是非常值得的的。

总结

  • 变量无处不在。在 JavaScript 中使用变量时,首选 const,其次是 let。
  • 尽可能缩小变量的作用域。同样,声明变量时要尽可能靠近其使用位置。
  • 合理的命名是非常重要的。要遵循以下规则:变量名称应该清楚无误地表明是用来保存哪些数据的。不要害怕使用更长的变量名:要追求清晰而不是简短。
  • 最后,最好用代码自己来解释代码。在高度复杂的地方,我更喜欢引入中间变量。

以上就是如何在JavaScript中正确处理变量的详细内容,更多关于JavaScript 处理变量的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
javascript attachEvent绑定多个事件执行顺序问题
Oct 20 Javascript
JS中判断null、undefined与NaN的方法
Mar 26 Javascript
json属性名为什么要双引号(个人猜测)
Jul 31 Javascript
node.js中的buffer.Buffer.byteLength方法使用说明
Dec 10 Javascript
jQuery中的jQuery()方法用法分析
Dec 27 Javascript
javascript实现Email邮件显示与删除功能
Nov 21 Javascript
js流动式效果显示当前系统时间
May 16 Javascript
JS中页面与页面之间超链接跳转中文乱码问题的解决办法
Dec 15 Javascript
JavaScript之浏览器对象_动力节点Java学院整理
Jul 03 Javascript
JavaScript实现左右滚动电影画布
Feb 06 Javascript
解决Element中el-date-picker组件不回填的情况
Nov 07 Javascript
JavaScript选择器函数querySelector和querySelectorAll
Nov 27 Javascript
Vue通过阿里云oss的url连接直接下载文件并修改文件名的方法
Dec 25 #Vue.js
vue使用require.context实现动态注册路由
Dec 25 #Vue.js
vue 使用rules对表单字段进行校验的步骤
Dec 25 #Vue.js
vue 实现基础组件的自动化全局注册
Dec 25 #Vue.js
vue 使用class创建和清除水印的示例代码
Dec 25 #Vue.js
React中使用Vditor自定义图片详解
Dec 25 #Javascript
基于vue+echarts数据可视化大屏展示的实现
Dec 25 #Vue.js
You might like
php遍历所有文件及文件夹的方法深入解析
2013/06/08 PHP
PHP云打印类完整示例
2016/10/15 PHP
PHP操作redis实现的分页列表,新增,删除功能封装类与用法示例
2018/08/04 PHP
Opacity.js
2007/01/22 Javascript
jquery将一个表单序列化为一个对象的方法
2013/12/02 Javascript
Node.js 服务器端应用开发框架 -- Hapi.js
2014/07/29 Javascript
Windows系统中安装nodejs图文教程
2015/02/28 NodeJs
JavaScript中的时间处理小结
2016/02/24 Javascript
js实现的简单图片浮动效果完整实例
2016/05/10 Javascript
关于Vue.js一些问题和思考学习笔记(1)
2016/12/02 Javascript
深入解析ES6中的promise
2018/11/08 Javascript
使用VUE+iView+.Net Core上传图片的方法示例
2019/01/04 Javascript
js实现删除li标签一行内容
2019/04/16 Javascript
javascript的惯性运动实现代码实例
2019/09/07 Javascript
vue 使用鼠标滚动加载数据的例子
2019/10/31 Javascript
layui 弹出层值回传解决方式
2019/11/14 Javascript
Vue如何将页面导出成PDF文件
2020/08/17 Javascript
Django中实现一个高性能计数器(Counter)实例
2014/07/09 Python
python实现进程间通信简单实例
2014/07/23 Python
使用Python对SQLite数据库操作
2017/04/06 Python
python3.6连接MySQL和表的创建与删除实例代码
2017/12/28 Python
flask中使用蓝图将路由分开写在不同文件实例解析
2018/01/19 Python
使用Flask集成bootstrap的方法
2018/07/24 Python
Pandas时间序列:重采样及频率转换方式
2019/12/26 Python
python 使用OpenCV进行简单的人像分割与合成
2021/02/02 Python
Python使用pyenv实现多环境管理
2021/02/05 Python
JD Sports马来西亚:英国领先的运动鞋和运动服饰零售商
2018/03/13 全球购物
动物学专业毕业生求职信
2013/10/11 职场文书
烹调加工管理制度
2014/02/04 职场文书
高中军训感想300字
2014/03/04 职场文书
英语专业求职信
2014/07/08 职场文书
领导干部保密承诺书
2014/08/30 职场文书
2014幼儿园卫生保健工作总结
2014/12/05 职场文书
“学党章、守党纪、讲党规”学习心得体会
2016/01/14 职场文书
MYSQL 运算符总结
2021/11/11 MySQL
对讲机知识
2022/04/07 无线电