前言

今天在Codewars刷题,碰到一个7kyu(这个等级,学过一点js的人,都会做)等级的题目,题目很简单:

求累加和,并对异常情况进行特殊处理。看着非常简单,事实上并不难。我的第一次代码:

// ?????
var SequenceSum = (function () {function SequenceSum () { }var sum = 0var str = ''SequenceSum.showSequence = function (count) {for (let i = 0; i < count; i++) {str += `${i}+`sum += i}sum += countif (count < 0) return `${count}<0`;if (count == 0) return `${count}=0`;return `${str}${count} = ${sum}`};return SequenceSum;
})();

测试结果:

但是在自己本地跑代码, 整个结果是没有错误的。看了上面的结果,错误的输出都有0+1+2+3+4+5+这段,然而这段代码正好是我在循环中所定义的,看来在测试的时候,对于第一次循环时所产生的结果并没有进行CG。

引入正题

var,let,const 声明变量

JavaScript是弱类型语言,可以不需要声明变量而直接使用。这样虽然简单但不易发现变量名方面的错误,所以不建议这样做。通常的做法是在使用JavaScript变量前先声明变量。目前,JavaScript变量声明方式有3种,分别是使用var、let和const关键字声明。其中,使用var声明变量,是ECMAScript6版本以前一直使用的方式,由于这种方式声明的变量在某些情况下会导致一些问题,因而在ECMAScript6版本中增加了使用let和const两种方式声明变量。

如何声明变量

老生常谈,我就不多写了。

var

方式一:var 变量名;
方式二:var 变量名1,变量名2,…,变量名n;
方式三:var 变量名1 = 值1,变量名2 = 值2,…,变量名n = 值n;

let

方式一:let 变量名;
方式二:let 变量名1,变量名2,…,变量名n;
方式三:let 变量名1=值1,变量名2=值2,…,变量名n=值n;

const

const 变量名 = 值;

需要特别注意的是:使用const声明变量时,必须给变量赋初值,且该值在整个代码的运行过程中不能被修改。另外,变量也不能重复多次声明。这些要求任何一点没满足都会报错。

三者区别

  1. 变量初始化要求不同:var和let声明变量时可以不需要初始化,没有初始化的变量的值为“undefined”,在代码的运行过程中变量的值可以被修改。const声明变量时必须初始化,并且在代码的整个运行过程中不能修改初始化值,否则运行时会报错。
  2. 变量提升的支持不同:var声明支持变量提升,而const和let声明不支持变量提升。变量提升
  3. 级作用域的支持不同:var声明的变量,不支持块级作用域,let和const声明的变量支持块级作用域。凡是使用一对花括号“{}”括起来的代码都称为一个代码块。所谓块级作用域,指的是有效范围为某个代码块,离开了这个代码块,变量将失效。
if (true) { let num = 3; const msg = "How are you?";
}
alert(num); //num为块级变量,离开判断块后无效,所以报:Uncaught ReferenceError
alert(msg); //msg为块级变量,离开判断块后无效,所以报:Uncaught ReferenceError
for (let i = 0; i < 9; i ++ ) {      var j = i;
}
alert(i);  //i为块级变量,离开循环块后无效,所以报:Uncaught ReferenceError
alert(j);  //j为全局变量,离开循环块后仍有效,所以运行正常,输出结果:8
  1. 重复声明:在同一个作用域中,var可以重复声明同一个变量,let和const不能重复声明同一个变量。
var gv1 = "JavaScript";
let gv2 = "JS";
const number = "10000";
var gv1 = "VBcript";   //correct
let gv2 = "JScript";   //Uncaught SyntaxError:Identifier'gv2'has already been declared
const number = "20000";//Uncaught SyntaxError:Identifier'number'has already been declared
alert(gv1);
alert(gv2);
alert(number);
  1. let和const存在暂时性死区:当块中存在let/const声明语句时,let/const声明的变量就绑定到这个当前块作用域,不会受外部变量的影响,也不会影响外部变量。这个特点导致了在块作用域中,块变量在块开始到块变量声明之间出现了一个称为“暂时性死区”的区域。在“暂时性死区”中使用块变量,将会导致ReferenceError。
var msg = "JavaScript";
var p = 123;
if(true){console.log("块内输出msg:" + msg);//Uncaught ReferenceError: Cannot access 'msg' before initializationconsole.log("块内输出p:" + p);//UVM79:5 Uncaught ReferenceError: Cannot access 'p' before initializationlet msg = "JScript";const p = 456;
}
console.log("块外输出msg:" + msg); //③
console.log("块外输出p:" + p); //④

上面报的错误:VM79:5 Uncaught ReferenceError: Cannot access 'msg' before initialization,其实就是之前的:Uncaught ReferenceError:msg is not defined
这个错误原因是因为①和②处代码处在“暂时性死区”中,由此也可见,块变量不会受外部变量影响。

总结

上面写到的区别,其实注重于块级作用域的问题,而我做的题目就是因为块级作用域从而导致了内存重复读取或者没有清楚块内内存的问题。修改代码如下:

var SequenceSum = (function () {function SequenceSum () { }SequenceSum.showSequence = function (count) {let sum = 0let str = ''for (let i = 0; i < count; i++) {str += `${i}+`sum += i}sum += countif (count < 0) return `${count}<0`;if (count == 0) return `${count}=0`;return `${str}${count} = ${sum}`};return SequenceSum;
})();

将之前的var进行删除,修改成为let 进行块级作用域内部的定义。从而修复了之前出现的bug。

再谈Js定义变量,你不得不踩的那些坑相关推荐

  1. 再谈js对象数据结构底层实现原理-object array map set

    2019独角兽企业重金招聘Python工程师标准>>> 如果有java基础的同学,可以回顾下<再谈Java数据结构-分析底层实现与应用注意事项>:java把内存分两种:一 ...

  2. 再谈 JS中的模块规范(CommonJS,AMD,CMD)来自玉伯的seajs分析

    随着互联网的飞速发展,前端开发越来越复杂.本文将从实际项目中遇到的问题出发,讲述模块化能解决哪些问题,以及如何使用 Sea.js 进行前端的模块化开发. 恼人的命名冲突 我们从一个简单的习惯出发.我做 ...

  3. JS之父再谈JS历史(一)

    译自[url=http://weblogs.mozillazine.org/roadmap/archives/2008/04/popularity.html]Brendan Eich的Blog上Pop ...

  4. js中定义变量之②var let const的区别

    var 上一篇文章有讲过,是js定义变量的关键词. 但是在es6中,新添加了两个关键词,用于变量声明的关键词:let 和const 接下来就说一下var let 和const的区别: 首先说var 用 ...

  5. 再谈JSON -json定义及数据类型

    再谈json 近期在项目中使用到了highcharts ,highstock做了一些统计分析.使用jQuery ajax那就不得不使用json, 可是在使用过程中也出现了非常多的疑惑,比方说,什么情况 ...

  6. mysql declare与set的区别_浅谈MySQL存储过程中declare和set定义变量的区别

    在存储过程中常看到declare定义的变量和@set定义的变量.简单的来说,declare定义的类似是局部变量,@set定义的类似全局变量. 1.declare定义的变量类似java类中的局部变量,仅 ...

  7. 定义并调用函数输出 fibonacci 序列_科学网—Zmn-0351 薛问天:再谈数学概念的定义,评新华先生《0345》...

    Zmn-0351 薛问天:再谈数学概念的定义,评新华先生<0345> [编者按.下面是薛问天先生发来的文章.是对<Zmn-0345>新华先生文章的评论.现在发布如下,供网友们共 ...

  8. 调用另一个cpp的变量_再谈条件变量—从入门到出家

    再谈条件变量-从入门到出家 C语言--条件变量 条件变量是在线程中以睡眠的方式等待某一条件的发生: 条件变量是利用线程间共享的全局变量进行同步的一种机制: 一个线程等待"条件变量的条件成立& ...

  9. css里面的let,js中let和var定义变量的区别

    javascript 严格模式 第一次接触let关键字,有一个要非常非常要注意的概念就是"javascript 严格模式",比如下述的代码运行就会报错: let hello = ' ...

最新文章

  1. springer journal recommendation tool
  2. OO Design之SOLID原则
  3. css3动画animation,transition
  4. 天池 在线编程 Character deletion
  5. 收藏!企业数据安全防护5条建议
  6. 额!Java中用户线程和守护线程区别这么大?
  7. 自动接听电话的另一种思路(只需要root权限)
  8. java excel导出下载_Java导出excel并下载功能
  9. MyEclipse下JSP代码提示
  10. 搭建Linux环境学习C语言
  11. 判断点P是否在三角形ABC内
  12. 怎么给视频换背景?只需4步,即可轻松换背景
  13. MySQL 闪回原理与实战
  14. HTML5+CSS3小实例:酷炫的ANIPLEX文字特效
  15. 计科学硕考研初试经验贴(11408)
  16. 2022湖南最新消防设施操作员模拟试题题库及答案
  17. 鼠友题库每日百题(三)
  18. 计算机应用基础实验指导ppt,2016计算机应用基础实验指导.ppt
  19. OSA-3空气温湿度传感器
  20. 多台PLC连接MES系统解决方案

热门文章

  1. CVPR 2021 | 超越卷积,自注意力模型HaloNet
  2. 霸榜 | 微软CV模型收获近 2k star
  3. 阿里人工智能实验室招聘计算机视觉算法专家-交互图像方向
  4. java选择排序不稳定_选择排序就这么简单 - Java3y的个人空间 - OSCHINA - 中文开源技术交流社区...
  5. 复练-软考网规-机房建设规范专题
  6. 热敏电阻如何查表计算温度_简单说说NTC热敏电阻
  7. 计算机在机械制造领域中的应用论文,高科技在机械制造工艺中的应用论文
  8. 华为鸿蒙系统学习笔记10-华为鸿蒙 OS 2.0 发布,源代码现已开放
  9. 避免缓冲区溢出的方法
  10. python显示小数点后几位数_Python编程从入门到实践-连载1(变量和简单数据类型)...