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. Android 版本更新升级

    推荐一款很好的版本升级开源框架: https://github.com/WVector/AppUpdate 个人地址:总结https://gitee.com/anan9303/AppVersionUp ...

  2. php简单工厂模式

    工厂类中有一个创建对象的方法,根据传入参数的不同来生成不同的对象 class Operation extends Model{ private $numberA; private $numberB; ...

  3. Android开发:《Gradle Recipes for Android》阅读笔记1.7——仓库配置

    repositories块告诉gradle哪里去寻找依赖,默认的android studio使用jcenter或者mavenCentral.jcenter仓库位于https://jcenter.bin ...

  4. 内核源码阅读vim+cscope+ctags+taglist

    杜斌博客:http://blog.db89.org/kernel-source-read-vim-cscope-ctags-taglist/ 武特博客:http://edsionte.com/tech ...

  5. TLE之前,没有一个节点叫失败!!!

    我想我十八年来记忆最深刻的夜晚,大概便是在吉林大学燥热的宿舍里,穿着橘黄色的短袖,努力咽下大口大口的雪碧.那天晚上我仰躺在吉大热得几乎不能入眠的床板上,一动不动,看夏夜里打不尽的蚊子在惨白的天花板下飞 ...

  6. python3使用SMTP发送邮件

    环境:python3 ,IDE : pycharm 非常奇怪的是,用163发送邮件,如果电脑连校园网发送,会被当成垃圾邮件拒绝 如果用手机开热点就可以正常发送 代码如下 #!/usr/bin/pyth ...

  7. Permutation Descent Counts(递推)

    1968: Permutation Descent Counts Submit Page   Summary   Time Limit: 1 Sec     Memory Limit: 128 Mb  ...

  8. 160823、ionic上拉/下拉更新数据

    <!DOCTYPE html> <html ng-app="myApp"> <head> <meta charset="UTF- ...

  9. Linux 常用命令缩写及对应的

    0.项目名: Linux -- LINUs' uniX (开个玩笑不是这样的,别当真) GNU -- Gnu is Not Unix1.目录名: /boot:顾名思义 /root :同上 /run:同 ...

  10. BaseServlet 介绍

    1. BaseServlet 的作用 让一个Servlet可以处理多种不同的请求,不同的请求调用Servlet的不同方法. 2. 实现原理 客户端发送请求时, 必须多给出一个参数, 用来说明要调用的方 ...