今天来说说es6的语法,最基础的也就是var,let,const 的用法与区别了,我们来看看他们之间的恩怨情仇。
首先来说说var,这个只要是学过js的都知道,它是用来声明一个变量的,但是它在开发中也会遇到一些问题,比较难解决。先来看看下面的代码:

var str="hello world";
​
function testVar(){
  var str="hello";
}
testVar();
console.log(str);

这段代码的结果是 "hello world",这说明在var 申明的变量,即使是同样的名字,在不同的块中,在外层块中的变量优先级更高,也就是说,在外层优先使用并且只能使用当前块中的变量;而在他的内部块中的变量,比如说这个函数里面的str,他其实也是优先使用块内的str变量,会屏蔽掉外面的str变量,这是一点。再来看看下面一段代码

function variableHoisting(){
  if(condition){
    var test="hello javaScript";
  }else{
    console.log(test)
    //这里可以访问到test,但是它是undefined,因为初始化为它赋值成了undefined
  }
  //这里也可以访问到test
}

可能你会感到奇怪,我的var 申明的变量在if 代码块里面,为什么我的else里面也能访问呢,其实上面这段代码相当于下面这段代码

function variableHoisting(){
  var test;
  if(condition){
    test="hello javaScript";
  }else{
    console.log(test)
    //这里可以访问到test,但是它是undefined,因为初始化为它赋值成了undefined
  }
    //这里也可以访问到test
}

现在知道了吧?这就是所谓的变量提升,我在if里面申明的变量,其实浏览器在预解析的时候就对var ,以及function关键字的变量或者方法进行了处理,处理后的代码就是上面这段代码(当然,我之前讲过一篇函数声明与函数表达式的区别,你可以看看,你会知道更多。)看到这里,也许你不会感觉var 有什么不好的地方,再往下看看:

```javascript

var funcs = [];
for (var i = 0; i < 10; i++) {
  funcs.push(function() {
    console.log(i);
  });
}
funcs.forEach(function(func) {
  func(); // 输出数值 "10" 十次
});

可能你想的是输出0,1,2,3,4,5,6,7,8,9但是这不是正确答案,这只能输出10个10,为什么呢?因为循环完成过后,i已经是10了,再次调用的时候,这个i值在每次迭代过程中共享了。
下面我们就来引入一下let,以及const。let 也是用来申明变量的,但是他申明的变量是块级作用域,什么意思呢,看下面

function testLet(){
  if(condition){
    let str="hello let"
  }else{
    //这里访问不到str
  }
    //这里也访问不到str
}

看了上面,你也许就知道了什么是块级作用域,也就是一个大括号嘛,括号里面就是一块。用let申明的变量是没有之前所说的变量提升这一说的,所以在外部块里面是访问不到let申明的变量的。这样,之前说var缺陷的哪一块代码经过小小的改变就能正常输出0..9了,你看看

var funcs = [];
for (let i = 0; i < 10; i++) {
funcs.push(function () {
console.log(i);
});
}
funcs.forEach(function (func) {
func(); // 输出数值 0-9
});

这就是let,与var的一个小区别,当然如果说你申明变量的时候不指名是用的var,还是let,编译的时候会将这个变量解析为var申明的变量。

不管是var,还是let,他们是不能重复申明的,比如像下面这样

var str="var";
let str="let";

这样是会报错的,编译的时候,不能重复定义。

然后就是const了,这个其实就是常量的单词的英文缩写(constant),没错,这是用来申明一个常量的。什么事常量呢,顾名思义,就是一旦赋值就不能再改变了。比如说:

const MAX=3.1415926;
MAX=3.14;

这样是不行的,会报错,常量不能改变的。来看看const的循环,在最基础的for -i的循环里面,他是会报错的,运行一次过后就会报错,但是在for-in 循环里面他是不会报错的,当然在for-of循环里面也不会

var funcs = [],
object = {
  a: true,
  b: true,
  c: true
};
// 不会导致错误
for (const key in object) {
  funcs.push(function () {
  console.log(key);
  });
}
funcs.forEach(function (func) {
  func(); // 依次输出 "a"、 "b"、 "c"
});

这样是不会报错的,来看看究竟是为什么呢?

上面说了,const申明的变量是不能改变的,但是,我们试试申明一个对象呢,然后改变对象里面的属性的值。

const object={
name:"学习笔记",
age:18
}
console.log(object.name)
​
object.name="hello world"
console.log(object.name)

这段代码,第一个会打印出来“学习笔记”,第二个会打印出来“hello world”,为什么呢?原因在这,其实,这段代码改变的不是object这个对象变量,而是这个变量的属性,知道了这个就不难理解为什么在for-in ,for-of循环里面,const不会报错了吧?如果对你有帮助的话,记得点个关注哦,如果你发现文中有错误,记得帮我指出来。

微信公众号

ES6语法:var、let、const的区别详解的更多相关文章

  1. ES6 新增声明变量的 var let const 的区别详解

    var 如果使用关键字 var 声明一个变量,那么这个变量就属于当前的函数作用域,如果声明是发生在任何函数外的顶层声明,那么这个变量就属于全局作用域. let 1.let 声明的变量具有块作用域的特征 ...

  2. var、let和const的区别详解

      let 和 const 是 ECMAScript6 新推出的特性,其中 let 是能够替代 var 的"标准",所以我们探讨 var.let 和 const 的区别,首先应该知 ...

  3. ES6中var/let/const的区别

    let的含义及let与var的区别: let 声明的变量只在它所在的代码块有效: 如下: for (let i = 0; i < 10; i++) { console.log(i); } con ...

  4. 【ES6 】var/let/const的区别

    var 声明变量 没有区级作用域 可以预解析 可以重复定义 声明的全局变量属于顶层对象(window)的属性 let 声明变量 有块级作用域 没有预解析 不可以重复定义 声明的全局变量不属于顶层对象( ...

  5. var和let的区别(详解)

    1. 作用域 通过var定义的变量,作用域是整个封闭函数,是全域的 . 通过let定义的变量,作用域是在块级或是子块中. function varTest() { var x = 1; if (tru ...

  6. 【前端面试】(四)JavaScript var let const的区别

    视频链接: JavaScript var let const的区别 - Web前端工程师面试题讲解 参考链接: JavaScript 变量 JavaScript Let JavaScript Cons ...

  7. var let const 的区别

    Var let const 的区别 1.Var 定义的变量存在变量提升,而了let和const不存在变量提升.即在定义的变量代码上使用该变量,var的会输出undefined,而let的会报错. 2. ...

  8. 李洪强iOS经典面试题155 - const,static,extern详解(面试必备)

    李洪强iOS经典面试题155 - const,static,extern详解(面试必备) 一.const与宏的区别(面试题): const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽 ...

  9. php 去除html标记--strip_tags与htmlspecialchars的区别详解

    php 去除html标记--strip_tags与htmlspecialchars的区别详解 作者: 字体:[增加 减小] 类型:转载 时间:2013-06-26   本篇文章是对php中去除html ...

随机推荐

  1. HTML 标签的 target 属性

    定义和用法 target 属性规定在何处打开 action URL. 属性值 值 描述 _blank 在新窗口中打开. _self 默认.在相同的框架中打开. _parent 在父框架集中打开. _t ...

  2. [LC] 108. Convert Sorted Array to Binary Search Tree

    Given an array where elements are sorted in ascending order, convert it to a height balanced BST. Fo ...

  3. [LC] 13. Roman to Integer

    Roman numerals are represented by seven different symbols: I, V, X, L, C, Dand M. Symbol Value I 1 V ...

  4. python-django框架-电商项目-购物车模块开发_20191125

    python-django框架-电商项目-购物车模块开发 商品详情页js代码: 在商品详情页,有加入购物车按钮, 点击加减号可以增加减少,手动输入也可以, 点击加入购物车,就要加过去, 先实现加减的操 ...

  5. 解密优秀博士成长史 ——微软亚洲研究院首届博士生学术论坛Panel讨论经验总结

    --微软亚洲研究院首届博士生学术论坛Panel讨论经验总结" title="解密优秀博士成长史 --微软亚洲研究院首届博士生学术论坛Panel讨论经验总结"> 编者 ...

  6. struts2 标签s:select在table中单行显示

    <table class="query_form_table">             <tr>                 <th>用户 ...

  7. 批量修改ACCESS表列名

    问题来源:从ODBC导入数据到ACCESS 再从ACCESS导入到SQL数据库,ACCESS会多带个DBO. 所以需要批量修改ACCESS的表名. 首先需要引用ADOX引用方法:打开ACCESS的VB ...

  8. hibernate主键(generator)生成方式

    1) assigned 主键由外部程序负责生成,无需Hibernate参与. 2) hilo 通过hi/lo 算法实现的主键生成机制,需要额外的数据库表保存主键生成历史状态. 3) seqhilo 与 ...

  9. 关于安装了Vue-devtools插件但在浏览器控制台不显示的解决方案

    Google浏览器中开发调试的时候,右上角出现vue的图标,但是在开发者工具中没有出现vue调试(已在扩展程序中安装 Vue Devtools) 控制台却没有. 错误原因: 没显示调试工具的原因是用了 ...

  10. /lib64/libc.so.6: version `GLIBC_2.18' not found报错解决

    今日安装一区块链服务时报错:/lib64/libc.so.6: version `GLIBC_2.18' not found,检查后现有的glibc版本是2.17,然后参考https://www.ji ...