如何在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:void(0)的真正含义实例分析
Aug 20 Javascript
在IE和VB中支持png图片透明效果的实现方法(vb源码打包)
Apr 01 Javascript
查看大图功能代码jquery版
Nov 05 Javascript
javascript 循环调用示例介绍
Nov 20 Javascript
编程语言JavaScript简介
Oct 16 Javascript
js使用DOM操作实现简单留言板的方法
Apr 10 Javascript
JavaScript中误用/g导致的正则test()无法正确重复执行的解决方案
Jul 27 Javascript
jQuery操作复选框(CheckBox)的取值赋值实现代码
Jan 10 Javascript
基于JavaScript实现无限加载瀑布流
Jul 21 Javascript
详解Vue路由History mode模式中页面无法渲染的原因及解决
Sep 28 Javascript
Angular6新特性之Angular Material
Dec 28 Javascript
详解element-ui 表单校验 Rules 配置 常用黑科技
Jul 11 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
利用 window_onload 实现select默认选择
2006/10/09 PHP
php htmlentities和htmlspecialchars 的区别
2008/08/18 PHP
基于php无限分类的深入理解
2013/06/02 PHP
PHP 输出URL的快捷方式示例代码
2013/09/22 PHP
PHP实现通过中文字符比率来判断垃圾评论的方法
2014/10/20 PHP
十幅图告诉你什么是PHP引用
2015/02/22 PHP
PHP仿qq空间或朋友圈发布动态、评论动态、回复评论、删除动态或评论的功能(上)
2017/05/26 PHP
一个判断email合法性的函数[非正则]
2008/12/09 Javascript
js封装的textarea操作方法集合(兼容很好)
2010/11/16 Javascript
jQuery.each()用法分享
2012/07/31 Javascript
jQuery实现统计复选框选中数量
2014/11/24 Javascript
js控制元素显示在屏幕固定位置及监听屏幕高度变化的方法
2015/08/11 Javascript
JS 对象(Object)和字符串(String)互转方法
2016/05/20 Javascript
jquery 删除节点 添加节点 找兄弟节点的简单实现
2016/12/07 Javascript
微信小程序开发教程-手势解锁实例
2017/01/06 Javascript
Vue中组件之间数据的传递的示例代码
2017/09/08 Javascript
Less 安装及基本用法
2018/05/05 Javascript
js中位运算的运用实例分析
2018/12/11 Javascript
Element UI框架中巧用树选择器的实现
2018/12/12 Javascript
其实你可以少写点if else与switch(推荐)
2019/01/10 Javascript
mocha的时序规则讲解
2019/02/16 Javascript
jquery+ajax实现上传图片并显示上传进度功能【附php后台接收】
2019/06/06 jQuery
js字符串类型String常用操作实例总结
2019/07/05 Javascript
JavaScript复制变量三种方法实例详解
2020/01/09 Javascript
JS实现前端路由功能示例【原生路由】
2020/05/29 Javascript
python修改注册表终止360进程实例
2014/10/13 Python
python实现报表自动化详解
2017/11/16 Python
python编写Logistic逻辑回归
2020/12/30 Python
python爬取网页内容转换为PDF文件
2020/07/28 Python
TENSORFLOW变量作用域(VARIABLE SCOPE)
2020/01/10 Python
薇诺娜官方网上商城:专注敏感肌肤
2017/05/25 全球购物
机械专业毕业生推荐信范文
2013/11/25 职场文书
煤矿安全演讲稿
2014/05/09 职场文书
2015年度女工工作总结
2015/10/22 职场文书
PHP 技巧 * SVG 保存为图片(分享图生成)
2021/04/02 PHP
Go语言编译原理之变量捕获
2022/08/05 Golang