https://stackoverflow.com/questions/762011/whats-the-difference-between-using-let-and-var-to-declare-a-variable-in-jav

答案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?的更多相关文章

  1. Javascript——概述 && 继承 && 复用 && 私有成员 && 构造函数

    原文链接:A re-introduction to JavaScript (JS tutorial) Why a re-introduction? Because JavaScript is noto ...

  2. 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 ...

  3. 【译】PHP的变量实现(给PHP开发者的PHP源码-第三部分)

    文章来自:http://www.aintnot.com/2016/02/12/phps-source-code-for-php-developers-part3-variables-ch 原文:htt ...

  4. Expression Tree Basics 表达式树原理

    variable point to code variable expression tree data structure lamda expression anonymous function 原 ...

  5. Groovy 模版引擎

    1. Introduction Groovy supports multiple ways to generate text dynamically including GStrings, print ...

  6. js 日期按年月日加减

    <script> function isleapyear(year) { if(parseInt(year)%4==0 && parseInt(year)%100!=0)r ...

  7. coffeescript 1.8.0 documents

    CoffeeScript is a little language that compiles into JavaScript. Underneath that awkward Java-esque ...

  8. JavaScript闭包的底层运行机制

    转自:http://blog.leapoahead.com/2015/09/15/js-closure/ 我研究JavaScript闭包(closure)已经有一段时间了.我之前只是学会了如何使用它们 ...

  9. SAS Annotated Output GLM

    SAS Annotated Output GLM   在使用SAS过程中,proc glm步输出离差平方和有4种算法,分别是SS1 SS2 SS3 SS4 下面文章介绍了其中SS3的具体计算步骤和例子 ...

随机推荐

  1. spring-security+hibernate4+quartz实现的心跳检测项目(转 收藏)

    转自:http://www.52itstyle.com/thread-27470-1-1.html HeartBeat. ~2 Z8 U! ?8 r心跳检测各类应用服务器(如Tomcat,Jetty) ...

  2. mongo-connector来同步mongo

    个人博客:https://blog.sharedata.info/ 最近需要做mongo之间的同步,因此还是选择之前的工具mongo-connectorgitHub文档:https://github. ...

  3. JavaScript严格模式为何要禁用With语句

    看了很多遍JavaScript严格模式,其中有说“禁用With语句”,以前看到这都是骑马观花,一带而过,因为平时就很少用到这个语句,禁不禁用对自己关系都不是很大.今天禁不住想知道为何“严格模式”就容不 ...

  4. 数据类型比较:Long和BigDecimal

    1.基本类型: 基本类型可以用:">" "<" "==" 2.基本类型包装类:(对象类型) 2.1 Long 型: 要比较两个L ...

  5. Java基础 - 流程控制语句

    package com.demo4; /* * 流程控制语句 * 流程控制语句分类: * 顺序结构 * 代码从上往下按照顺序执行 * * 选择结构 * if * if (关系表达式1) { * 语句体 ...

  6. Vue.js中this.$nextTick()的使用

    this.$nextTick()将回调延迟到下次 DOM 更新循环之后执行.在修改数据之后立即使用它,然后等待 DOM 更新.它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自 ...

  7. Beautiful Soup 4.2.0 文档

    Beautiful Soup 4.2.0 文档 Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方 ...

  8. 001-Eclipse、idea集成javap查看字节码、javap说明

    一.概述 分析java语言特性的一个好帮手是使用javap工具查看java编译后的字节码,如何在eclipse中配置javap工具快速查看java字节码. 二.Eclipse集成javap查看字节码 ...

  9. zabbix3.2.4监控MySQL5.7.16状态

    一.添加监控用户mysql> grant all privileges on *.* to 'zabbix'@'localhost' identified by 'zabbix';mysql&g ...

  10. Python学习笔记3_数据类型

    Python数据类型:数字.字符串.列表.元祖.字典 一.数字类型:(整型.长整型.浮点型.复数型) 1.整型(int):表示范围-2,147,483,648到2,147,483,647 2.长整型( ...