•   let与var

  在js中声明一个变量除了一个var 还有一个let的声明。对于var 在前面的作用域中已经讲过,这次主要说下二者的区别:

在MDN上有这样的一个demo:

var list = document.getElementById("list");for (var i = 1; i <= 5; i++) {var item = document.createElement("LI");item.appendChild(document.createTextNode("Item " + i));let j = i;item.onclick = function (ev) {console.log("Item " + j + " is clicked.");};list.appendChild(item);
}

上面这段代码的意图是创建5个li,点击不同的li能够打印出当前li的序号。如果不用let,而改用var的话,将总是打印出 Item 5 is Clicked,因为 j 是函数级变量,5个内部函数都指向了同一个 j ,而 j 最后一次赋值是5。

对于上面的结果如果不使用let的话,也是有办法破的。方法就是用一个闭包把j的作用域给包起来。修改如下:

<script>
var list = document.getElementById("list");
for (var i = 1; i <= 5; i++) {var item = document.createElement("LI");item.appendChild(document.createTextNode("Item " + i));var j = i;item.onclick = (function(j){return function () {console.log("Item " + j + " is clicked.");}
})(j);list.appendChild(item);
}
</script>

上面的是采用的闭包的方式在绑定的时候已经把j的值已经传递给对应的click事件了,所以能够实现相同的结果。如此很是精妙!但是对于程序的易性来说是一个不小的考验。

下面开始说说let为什么能够实现如此的结果:

let 允许把变量的作用域限制在块级域中。与 var 不同处是:var 申明变量要么是全局的,要么是函数级的,而无法是块级的。再看几个官方的demo.

在程序或者函数的顶层,let 的表现就象 var 一样:

function varTest() {var x = 31;if (true) {var x = 71;  // same variable!console.log(x);  // 71
  }console.log(x);  // 71
}function letTest() {let x = 31;if (true) {let x = 71;  // different variableconsole.log(x);  // 71
  }console.log(x);  // 31
}

上面的结果说明了let只在{}内使用。说到这里对开篇的那个问题就容易解释了。

用了let后,j 变成块级域(也就是花括号中的块,每进入一次花括号就生成了一个块级域),所以 5 个内部函数指向了不同的 j 。如果两个定义都在最外层则效果是一样,如下:

var x = 'global';
let y = 'global';
console.log(this.x);
console.log(this.y);

  • let 的暂存死区与错误

在同一个函数或同一个作用域中用let重复定义一个变量将引起 TypeError.

if (x) {let foo;let foo; // TypeError thrown.
}

然而,在变量声明之前引用这个变量会导致一个 ReferenceError的结果, 因为let变量 在"暂存死区" (从块的开始到声明这段).

function do_something() {console.log(foo); // ReferenceErrorlet foo = 2;
}

在 switch 申明中你可能会遇到这样的错误,因为一个switch只有一个作用块.

switch (x) {case 0:let foo;break;case 1:let foo; // TypeError for redeclaration.break;
}

循环体中是可以引用在for申明时用let定义的变量,尽管let不是出现在大括号之间.

var i=0;
for ( let i=i ; i < 10 ; i++ ) {console.log(i);
}

let提供了一种在块的范围内获取变量的值,而不会影响块外面名字相同的变量的值的方法。

var x = 5;
var y = 0;let (x = x+10, y = 12) {console.log(x+y); // 27
}console.log(x + y); // 5

总结一下,对于let来说在某些地方确实有其长处的地方,同样也弥补了的js中块作用域的空白。

转载于:https://www.cnblogs.com/OceanHeaven/p/5472181.html

第28篇 js中let和var相关推荐

  1. JS中 let 和var的区别

    JS中let和var 的区别 简单介绍let var的常见变量提升 ES6可以用let定义块级作用域变量 let配合for循环的独特应用 let没有变量提升与暂时性死区 let变量不能重复声明 简单介 ...

  2. uniapp 获取到js文件var一个变量怎么获取到这个变量值_浅析Js中const,let,var的区别及作用域...

    理解:let变量的作用域只能在当前函数中 js中const,let,var的区别及作用域_lianzhang861的博客-CSDN博客​blog.csdn.net 全局作用域中,用 const 和 l ...

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

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

  4. 前端开发:JS中let、var和const的区别详解

    前言 前端开发过程中,JS声明变量的关键字想必开发者都不陌生,而且使用的频率在前端开发过程中也是数一数二的.JS中声明变量的关键字有三个let.var和const,但是三者的使用对比和区别也是非常重要 ...

  5. js 浅拷贝直接赋值_第二十二篇 JS中浅拷贝的方法有哪些?

    重要:什么是拷贝?之前也写过类似的文章,大家可以看<理解js的深拷贝和浅拷贝原理和实现的方法> 首先来直观的感受一下什么是拷贝. let arr = [1, 2, 3]; let newA ...

  6. 第22篇 js中的this指针的用法

    前面把js的相关知识总结了下,今天把js中的上下文的this,对于强类型语言,this的用法非常的单一,因为他们没有js特有的动态绑定. 首先看下面代码: function funcA() {this ...

  7. js中Let和Var的区别

    写在前面: 本文转载自:https://www.cnblogs.com/fly_dragon/p/8669057.html 作者:FlyDragon 出处:http://www.cnblogs.com ...

  8. 前端笔记—第15篇js中的DOM操作

    获取事件源 document.getElementById() document.getElementsByClass() document.getElementsByTagName() docume ...

  9. js中let和var定义变量的区别

    let变量之前没见过,刚遇到,探探究竟. 以下转自:http://blog.csdn.net/nfer_zhuang/article/details/48781671 声明后未赋值,表现相同 (fun ...

最新文章

  1. 20.27 分发系统介绍 20.28 expect脚本远程登录 20.29 expect脚本远程执行
  2. JSR 303 - Bean Validation 介绍及最佳实践
  3. 软件测试性能测试结果,软件性能测试结果分析工具的研究与设计
  4. elasticsearch索引和映射
  5. FFT快速傅立叶变换
  6. java语言特点 字符串不变_面试必问:Java中String类型为什么设计成不可变的?
  7. 对称二叉树(信息学奥赛一本通-T1368)
  8. Everything Toolbar – 用 Everything 替换 Win 10 任务栏系统搜索框
  9. 世界公认的第一商人——成就犹太商人的15个信条
  10. 递归删除.svn文件夹以及文件
  11. C++中STL-队列和优先队列
  12. 云服务器怎么配置文件,云服务器网卡怎么配置文件
  13. python学习笔记——叁之修改配置文件
  14. CAD贱人工具箱6.0免注册
  15. linux报错的Syntax error “(“ 的解决方法
  16. 《解构产品经理互联网产品策划入门》PDF+《互联网产品运营产品经理的10堂精英课》PDF分析...
  17. iOS崩溃日志符号化及NLP聚类实现
  18. 14期《读万卷书,行万里路》4月刊
  19. 未来量子计算机运算速度,中国科学家实现 “量子霸权”,计算速度比超级计算机快100万亿倍...
  20. 3D MAX入门篇(2)制作飞船绕山飞行动画

热门文章

  1. 理解 UDDI(统一描述、发现和集成)
  2. 多个微服务控制台的多窗口展示
  3. 一个线程中lock用法的经典实例
  4. Could not open ServletContext resource [/WEB-INF/springmvc-servlet.xml]【解决方案】
  5. 对HA的简单认识以及HA集群删除
  6. 傻子的成长日记,编程路上 2016-04-07
  7. 手机上 a 标签妙用
  8. OpenSceneGraph 笔记--如何导出三角形数据
  9. TokuDB · 引擎特性 · HybridDB for MySQL高压缩引擎TokuDB 揭秘
  10. Spring Boot 动态数据源(多数据源自己主动切换)