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 boot logback】spring boot中logback日志乱码问题

    在初次使用logback的自定义配置文件完整的控制spring boot日志后,发现了一个无法忍受的问题,就是日志乱码. 控制台看到打印日志乱码如下: 而日志文件打开: 记事本打开 sublime打开 ...

  2. 01-K Code

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission ...

  3. oracle clob字段去除html标签

    通过正则表达式的方式去除html标签 select regexp_replace(content,'</?[^>]*>|nbsp;|&','') content from T ...

  4. 查看java进程的所有信息

    查看java 进程下的所有信息 ll /proc/pid/fd ru:ll /proc/24047/fd

  5. POJ 3259 Wormholes【bellman_ford判断负环——基础入门题】

    链接: http://poj.org/problem?id=3259 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22010#probl ...

  6. PLSQL 用的让自己更舒心点!

    每天开发时候  ,有时候会疲劳! 改下你的PLSQL 字体吧!

  7. 003-ARP地址解析协议

    一.概念 地址解析协议,即ARP(Address Resolution Protocol),是根据IP地址获取物理地址的一个TCP/IP协议.主机发送信息时将包含目标IP地址的ARP请求广播到网络上的 ...

  8. 如何配置一个路径,能够既适合Linux平台,又适合Windows平台,可以从这个路径中读取文件

    如何配置一个路径,能够既适合Linux平台,又适合Windows平台,可以从这个路径中读取文件? 目的:就是希望在项目的配置文件中配上一样的路径,不管协作者使用的是什么平台,都能够读到文件. 比如:L ...

  9. ModelForm组件介绍

    照抄自:http://www.jb51.net/article/126786.htm ModelForm组件如同它的名字一样就是把model和form结合起来,在有些场景可以起到意想不到的效果. 先来 ...

  10. Python 模块续 configparser、shutil、XML、paramiko、系统命令、

    一.configparse # 注释1 ; 注释2 [section1] # 节点 k1 = v1 # 值 k2:v2 # 值 [section2] # 节点 k1 = v1 # 值 1.获取所有节点 ...