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的具体计算步骤和例子 ...
随机推荐
- jqgrid 事件说明
Events(事件) 事件响应动作被设置为表格的属性,以下定义了行被选中时的响应: var lastSel; jQuery("#gridid").jqGrid({ ... o ...
- Win7系统安装 MySQL 5.7.23
1. 下载 MySQL 5.7版本:https://dev.mysql.com/downloads/mysql/5.7.html#downloads 2. 解压到指定文件夹,mysql根目录下创建my ...
- node.js 关于跨域和传递给前台参数
/*为app添加中间件处理跨域请求*/ app.use(function(req, res, next) { res.header("Access-Control-Allow-Origin& ...
- Hibernate 延迟加载的代理模式 和 Spring AOP的代理模式
Hibernate 延迟加载的代理模式 和 Spring AOP的代理模式 主题 概念 Hibernate 延迟加载的代理模式 Spring AOP的代理模式 区别和联系 静态代理和动态代理 概念 代 ...
- IntelliJ IDEA For Mac 快捷键 [转]
Mac键盘符号和修饰键说明 ⌘ Command ⇧ Shift ⌥ Option ⌃ Control ↩︎ Return/Enter ⌫ Delete ⌦ 向前删除键(Fn+Delete) ↑ 上箭头 ...
- <2013 08 13> TeX and LaTeX, some introduction
1. TeX是Donald E. Knuth教授的精心杰作,它是个功能非常强大的幕后排版系统,含有弹性很大,而且很低阶的排版语言.含有九百多条指令,用Pascal语言(的一个子集)写成. 2. T ...
- JVM 指令讲解
挺有意思的 转载记录下 转载自 https://www.cnblogs.com/f1194361820/p/8524666.html 原作者: 房继诺 JVM 指令 1.Demo 2.Clas ...
- selenium 用autoIT上传下载文件
一.下载安装AutoIT 下载并安装AutoIT,下载链接:https://www.autoitscript.com/site/autoit/ AutoIT安装成功后,可以在开始菜单下看到AutoIT ...
- JavaWeb—监听器Listener
1.简介 Listener是Servlet的监听器,Servlet 监听器用于监听一些重要事件的发生,监听器对象在事情发生前.发生后可以做一些必要的处理. JavaWeb里面的listener是通过观 ...
- 1.5 使用电脑测试MC20的发送英文短信功能
需要准备的硬件 MC20开发板 1个 https://item.taobao.com/item.htm?id=562661881042 GSM/GPRS天线 1根 https://item.taoba ...