第28篇 js中let和var
- 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);
- }
- console.log(x);
- }
- function letTest() {
- let x = 31;
- if (true) {
- let x = 71; // different variable
- console.log(x);
- }
- console.log(x);
- }
上面的结果说明了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); // ReferenceError
- let 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);
- }
- console.log(x + y);
总结一下,对于let来说在某些地方确实有其长处的地方,同样也弥补了的js中块作用域的空白。
第28篇 js中let和var的更多相关文章
- JS中let和var的区别
js中let和var定义变量的区别 let变量之前没见过,刚遇到,探探究竟. 以下转自:http://blog.csdn.net/nfer_zhuang/article/details/48781 ...
- js中 慎用for(var o in arrays) 遍历数组,for(var i,i< objects.length;i++)与for(var i,n = objects.length;i<n;i++) 的性能区别
原文:js中 慎用for(var o in arrays) 遍历数组,for(var i,i< objects.length;i++)与for(var i,n = objects.length; ...
- JS中const、var 和let的区别
今天第一次遇到const定义的变量,查阅了相关资料整理了这篇文章.主要内容是:js中三种定义变量的方式const, var, let的区别. 1.const定义的变量不可以修改,而且必须初始化. 1 ...
- 第22篇 js中的this指针的用法
前面把js的相关知识总结了下,今天把js中的上下文的this,对于强类型语言,this的用法非常的单一,因为他们没有js特有的动态绑定. 首先看下面代码: function funcA() { thi ...
- js中let和var的区别 不懂得加QQ 2270312758
js中使用let定义变量的时候,是需要使用严格模式的,我看到网上有的博客说:如果在不使用严格模式的情况下,使用let会报错,但是在实验的过程中,我直接定义了let变量而且也没有使用严格模式,并没有报任 ...
- js中的let\var\const
在JavaScript中有三种声明变量的方式:var.let.const.下文给大家介绍js中三种定义变量的方式const, var, let的区别. 1.const定义的变量不可以修改,而且必须初始 ...
- 如何HTML标签和JS中设置CSS3 var变量
一.HTML标签中设置CSS变量 如下: <div style="--color: #cd0000;"> <img src="mm.jpg" ...
- 关于js中的for(var in)遍历属性报错问题
之前遇到过这个问题,但是没找到问题的所在,将for(var i in array){} 改成了for(var i ;i<array.length;i++)循环,但是今天又遇到了,mark一下错 ...
- js中let和var定义变量的区别
let变量之前没见过,刚遇到,探探究竟. 以下转自:http://blog.csdn.net/nfer_zhuang/article/details/48781671 声明后未赋值,表现相同 (fun ...
随机推荐
- Mybatis学习(7)spring和mybatis整合
整合思路: 需要spring通过单例方式管理SqlSessionFactory. spring和mybatis整合生成代理对象,使用SqlSessionFactory创建SqlSession.(spr ...
- JS拖动技术--- 关于setCapture
<script type="text/javascript"> <!-- window.onload=function(){ objDiv = documen ...
- tomcat 安全文件夹(Java之负基础实战)
tomcat 解析网站的时候,会寻找一个文件叫 WEB-INF 这些文件外部无法访问
- MI & CI
目前,很多特征选择文献主要是依据对共信息的直观认识使用它,即:正值表示表型的存在使特征间依赖程度增加,是特征间存在相互作用的证据:负值表示表型的存在使特征间冗余性增加:零表示特征是相互独立的,或者说, ...
- C语言的位运算的优势
位运算加速技巧1. 如果乘上一个2的倍数数值,可以改用左移运算(Left Shift) 加速 300% x = x * 2;x = x * 64;//改为:x = x << 1; // 2 ...
- redhat6 + 11G RAC 双节点部署
一.配置网络环境 node1 [root@node1 ~]#vi/etc/sysconfig/network NETWORKING=yes NETWORKING_IPV6=no HOSTNAME= ...
- Raphael的set使用
Raphael的set使用 $(function() { initRaphael(); }); function initRaphael(e) { var paper = Raphael(0, 0, ...
- Pomelo聊天室框架
聊天室是验证服务器最典型的例子,Pomelo的运行架构: 在这个架构里,前端服务器也就是connector专门负责承载连接, 后端的聊天服务器则是处理具体逻辑的地方. 这样扩展的运行架构具有如下优势: ...
- spring mvc 资源包的映射
在springmvc.xml中进行设置: <?xml version="1.0" encoding="UTF-8"?> <beans xmln ...
- ARPU值分析
每用户平均收入(“ARPU)它由一个消费群体消费总额除以群体总人数得到. 活跃付费账户(“APA”) 平均同时在线玩家人数(“ACU”) 最高同时在线玩家人数(“PCU”)同时在线玩家数最高峰. 千人 ...