What's the difference between using “let” and “var” to declare a variable in JavaScript?
答案1
The difference is scoping. var is scoped to the nearest function block and let is scoped to the nearest enclosing block, which can be smaller than a function block. Both are global if outside any block.
Also, variables declared with let are not accessible before they are declared in their enclosing block. As seen in the demo, this will throw a ReferenceError exception.
var html = '';
write('#### global ####\n');
write('globalVar: ' + globalVar); //undefined, but visible
try {
write('globalLet: ' + globalLet); //undefined, *not* visible
} catch (exception) {
write('globalLet: exception');
}
write('\nset variables');
var globalVar = 'globalVar';
let globalLet = 'globalLet';
write('\nglobalVar: ' + globalVar);
write('globalLet: ' + globalLet);
function functionScoped() {
write('\n#### function ####');
write('\nfunctionVar: ' + functionVar); //undefined, but visible
try {
write('functionLet: ' + functionLet); //undefined, *not* visible
} catch (exception) {
write('functionLet: exception');
}
write('\nset variables');
var functionVar = 'functionVar';
let functionLet = 'functionLet';
write('\nfunctionVar: ' + functionVar);
write('functionLet: ' + functionLet);
}
function blockScoped() {
write('\n#### block ####');
write('\nblockVar: ' + blockVar); //undefined, but visible
try {
write('blockLet: ' + blockLet); //undefined, *not* visible
} catch (exception) {
write('blockLet: exception');
}
for (var blockVar = 'blockVar', blockIndex = 0; blockIndex < 1; blockIndex++) {
write('\nblockVar: ' + blockVar); // visible here and whole function
};
for (let blockLet = 'blockLet', letIndex = 0; letIndex < 1; letIndex++) {
write('blockLet: ' + blockLet); // visible only here
};
write('\nblockVar: ' + blockVar);
try {
write('blockLet: ' + blockLet); //undefined, *not* visible
} catch (exception) {
write('blockLet: exception');
}
}
function write(line) {
html += (line ? line : '') + '<br />';
}
functionScoped();
blockScoped();
document.getElementById('results').innerHTML = html;
Global:
They are very similar when used like this outside a function block.
let me = 'go'; // globally scoped
var i = 'able'; // globally scoped
However, global variables defined with let will not be added as properties on the global windowobject like those defined with var.
console.log(window.me); // undefined
console.log(window.i); // 'able'
Function:
They are identical when used like this in a function block.
function ingWithinEstablishedParameters() {
let terOfRecommendation = 'awesome worker!'; //function block scoped
var sityCheerleading = 'go!'; //function block scoped
}
Block:
Here is the difference. let is only visible in the for() loop and var is visible to the whole function.
unction allyIlliterate() {
//tuce is *not* visible out here
for( let tuce = 0; tuce < 5; tuce++ ) {
//tuce is only visible in here (and in the for() parentheses)
//and there is a separate tuce variable for each iteration of the loop
}
//tuce is *not* visible out here
}
function byE40() {
//nish *is* visible out here
for( var nish = 0; nish < 5; nish++ ) {
//nish is visible to the whole function
}
//nish *is* visible out here
}
Redeclaration:
Assuming strict mode, var will let you re-declare the same variable in the same scope. On the other hand, let will not:
'use strict';
let me = 'foo';
let me = 'bar'; // SyntaxError: Identifier 'me' has already been declared
'use strict';
var me = 'foo';
var me = 'bar'; // No problem, `me` is replaced.
答案2
let can also be used to avoid problems with closures. It binds fresh value rather than keeping an old reference as shown in examples below.
for(var i = 1; i < 6; i++) {
document.getElementById('my-element' + i)
.addEventListener('click', function() { alert(i) })
}
Code above demonstrates a classic JavaScript closure problem. Reference to the i variable is being stored in the click handler closure, rather than the actual value of i.
Every single click handler will refer to the same object because there’s only one counter object which holds 6 so you get six on each click.
General workaround is to wrap this in an anonymous function and pass i as argument. Such issues can also be avoided now by using let instead var as shown in code below.
'use strict';
for(let i = 1; i < 6; i++) {
document.getElementById('my-element' + i)
.addEventListener('click', function() { alert(i) })
}
What's the difference between using “let” and “var” to declare a variable in JavaScript?的更多相关文章
- Javascript——概述 && 继承 && 复用 && 私有成员 && 构造函数
原文链接:A re-introduction to JavaScript (JS tutorial) Why a re-introduction? Because JavaScript is noto ...
- JavaScript var, let, const difference All In One
JavaScript var, let, const difference All In One js var, let, const 区别 All In One 是否存在 hoisting var ...
- 【译】PHP的变量实现(给PHP开发者的PHP源码-第三部分)
文章来自:http://www.aintnot.com/2016/02/12/phps-source-code-for-php-developers-part3-variables-ch 原文:htt ...
- Expression Tree Basics 表达式树原理
variable point to code variable expression tree data structure lamda expression anonymous function 原 ...
- Groovy 模版引擎
1. Introduction Groovy supports multiple ways to generate text dynamically including GStrings, print ...
- js 日期按年月日加减
<script> function isleapyear(year) { if(parseInt(year)%4==0 && parseInt(year)%100!=0)r ...
- coffeescript 1.8.0 documents
CoffeeScript is a little language that compiles into JavaScript. Underneath that awkward Java-esque ...
- JavaScript闭包的底层运行机制
转自:http://blog.leapoahead.com/2015/09/15/js-closure/ 我研究JavaScript闭包(closure)已经有一段时间了.我之前只是学会了如何使用它们 ...
- SAS Annotated Output GLM
SAS Annotated Output GLM 在使用SAS过程中,proc glm步输出离差平方和有4种算法,分别是SS1 SS2 SS3 SS4 下面文章介绍了其中SS3的具体计算步骤和例子 ...
随机推荐
- node.js cmd常用命令
cmd1.c:如果我们想访问c盘,那么我们需要在命令行中输入c:就行了 2.cd..cd..就可以返回上层目录 3.cd mmcd mm即可访问mm文件夹 4.dir如果想查看该文件夹下有哪些文件,则 ...
- Lucene建立索引搜索入门实例
第一部分:Lucene建立索引 Lucene建立索引主要有以下两步:第一步:建立索引器第二步:添加索引文件准备在f盘建立lucene文件夹,然后 ...
- poj 3670(LIS)
// File Name: 3670.cpp // Author: Missa_Chen // Created Time: 2013年07月08日 星期一 21时15分34秒 #include < ...
- mysql with python
前言: 数据库为人类解决了三大问题:持久化存储.优化读写.数据标准化. MySQL它不是数据库,它是管理数据库的软件.MySQL管理了很多数据库.是典型的服务型数据库,需要TCP/IP去连接. MyS ...
- 图片热区——map的用法
<area>标记主要用于图像地图,通过该标记可以在图像地图中设定作用区域(又称为热点),这样当用户的鼠标移到指定的作用区域点击时,会自动链接到预先设定好的页面.其基本语法结构如下: 1 & ...
- 坑爹的 HTTPClient java.lang.NoSuchFieldError: INSTANCE
项目中需要用到httpclient ,maven配置如下 <dependency> <groupId>org.apache.httpcomponents</groupId ...
- Xamarin.Forms学习之Platform-specific API和文件操作
这篇文章的分享原由是由于上篇关于Properties的保存不了,调用SavePropertiesAsync()方法也不行,所以我希望通过操作文件的方式保存我的需要的数据,然后我看了一下电子书中的第二十 ...
- 前端发起resultUrl请求,服务端收到后做逆向处理,校验sign后,执行originUrl逻辑
originUrl=http://test.com:8080/user/alipay_phone?uid=123&amount=21.3第0步:前后端约定32位密钥KEY第一步:对参数按照ke ...
- SQL判断字符类型是否为数字
用ISNUMERIC函数 确定表达式是否为一个有效的数字类型. 语法 ISNUMERIC ( expression ) 参数 expression 要计算的表达式. 返回类型 int 注释 当输入表达 ...
- CentOS6.9添加环境变量
方法一:直接运行命令export PATH=$PATH:~/.composer/vendor/bin 使用这种方法,只会对当前会话有效,也就是说每当登出或注销系统以后,PATH 设置就会失效,只是临时 ...