如何在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 相关文章推荐
Auntion-TableSort国人写的一个javascript表格排序的东西
Nov 12 Javascript
超棒的javascript页面顶部卷动广告效果
Dec 01 Javascript
IE之动态添加DOM节点触发window.resize事件
Jul 27 Javascript
jQuery简单操作cookie的插件实例
Jan 13 Javascript
JavaScript常用字符串与数组扩展函数小结
Apr 24 Javascript
JS定时器实现数值从0到10来回变化
Dec 09 Javascript
JS简单实现表格排序功能示例
Dec 20 Javascript
提高JavaScript执行效率的23个实用技巧
Mar 01 Javascript
Angularjs 与 bower安装和使用详解
May 11 Javascript
浅谈KOA2 Restful方式路由初探
Mar 14 Javascript
微信小程序 image组件遇到的问题
May 28 Javascript
nuxt.js写项目时增加错误提示页面操作
Nov 05 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应用技巧
2008/03/27 PHP
PHP 字符串编码截取函数(兼容utf-8和gb2312)
2009/05/02 PHP
简单谈谈php中ob_flush和flush的区别
2014/11/27 PHP
一些主流JS框架中DOMReady事件的实现小结
2011/02/12 Javascript
js下拉菜单语言选项简单实现
2013/09/23 Javascript
表单序列化与jq中的serialize使用示例
2014/02/21 Javascript
javascript制作坦克大战全纪录(1)
2014/11/27 Javascript
js实现跟随鼠标移动且带关闭功能的图片广告实例
2015/02/26 Javascript
jQuery 实现评论等级好评差评特效
2016/05/06 Javascript
JavaScript学习笔记整理_简单实现枚举类型,扑克牌应用
2016/09/19 Javascript
Vue根据条件添加click事件的方式
2019/11/09 Javascript
python实现倒计时的示例
2014/02/14 Python
python监控网站运行异常并发送邮件的方法
2015/03/13 Python
python中string模块各属性以及函数的用法介绍
2016/05/30 Python
Python如何获取系统iops示例代码
2016/09/06 Python
Python探索之URL Dispatcher实例详解
2017/10/28 Python
Python实现句子翻译功能
2017/11/14 Python
Django model update的多种用法介绍
2020/03/28 Python
使用Pytorch来拟合函数方式
2020/01/14 Python
python 对任意数据和曲线进行拟合并求出函数表达式的三种解决方案
2020/02/18 Python
Python中内建模块collections如何使用
2020/05/27 Python
Expected conditions模块使用方法汇总代码解析
2020/08/13 Python
python在一个范围内取随机数的简单实例
2020/08/16 Python
解决Python3.8运行tornado项目报NotImplementedError错误
2020/09/02 Python
Python装饰器如何实现修复过程解析
2020/09/05 Python
css3实现针线缝合效果(图解步骤)
2013/02/04 HTML / CSS
canvas之万花筒效果的简单实现(推荐)
2016/08/16 HTML / CSS
CSS3 box-sizing属性详解
2016/11/15 HTML / CSS
美国领先的水果篮送货公司和新鲜水果供应商:The Fruit Company
2018/02/13 全球购物
实习报告评语
2014/04/26 职场文书
红与黑读书笔记
2015/06/29 职场文书
自信主题班会
2015/08/14 职场文书
导游词之舟山普陀山
2019/11/06 职场文书
Python基础之字符串格式化详解
2021/04/21 Python
前端传参数进行Mybatis调用mysql存储过程执行返回值详解
2022/08/14 MySQL