您好,欢迎访问一九零五行业门户网

javascript中var和let有什么区别

区别:1、var有变量提升,而let没有;2、let不允许在相同的作用域下重复声明,而var允许;3、let没有暂时性死区问题;4、let创建的全局变量没有给window设置对应的属性;5、let会产生块级作用域,var不会。
本教程操作环境:windows7系统、javascript1.8.5版、dell g3电脑。
想要了解var(es5)和let(es6)区别,首先就要了解es5下js的变量提升
一、变量提升(声)当浏览器开辟出供代码执行的栈内存后,代码并没有自上而下立即执行,而是继续做了一些事情:把当前作用域中所有带var/function关键字的进行提前的声明和定义 => 变量提升机制
带var的只是提前声明(declare)var a;,如果只声明没有赋值,默认值是undefined
例如:console.log(a);var a = 13;
输出:undefined
相当于:
var a; // 只声明没有赋值,默认为undefinedconsole.log(a);a = 13;
带function的不仅声明,而且还定义了(defined),准确来说就是让变量和某个值进行关联。二、let和var的区别1. let和const不存在变量提升机制
创建变量的六种方式中:var/function有变量提升,而let/const/class/import都不存在这个机制
2. var允许重复声明,而let不允许重复声明
在相同的作用域(或执行上下文中)
如果使用var/function关键词声明变量并且重复声明,是不会有影响的(声明第一次之后,之后再遇到就不会再重复声明了)但使用let/const就不行,浏览器会校验当前作用域中是否已经存在这个变量了,如果已经存在了,则再次基于let等重新声明就会报错在浏览器开辟栈内存供代码自上而下执行之前,不仅有变量提升的操作,还有很多其他的操作 => “词法解析”或者“词法检测”:就是检测当前即将要执行的代码是否会出现“语法错误 syntaxerror”,如果出现错误,代码将不会再执行(第一行都不会执行)
console.log(1) // => 这行代码就已经不会执行了let a = 12console.log(a)let a = 13 // => 此行出错:syntaxerror: identifier 'a' has already been declaredconsole.log(a)
所谓重复就是:不管之前通过什么方法,只要当前栈内存中存在了这个变量,我们使用let/const等重复再声明这个变量就是语法错误。eg:
console.log(a)var a = 12let a = 13 // => syntaxerror: identifier 'a' has already been declaredconsole.log(a)
console.log(a)let a = 13var a = 12 // => syntaxerror: identifier 'a' has already been declaredconsole.log(a)
3. let能解决typeof检测时出现的暂时性死区问题(let比var更严谨)
console.log(a)// => referenceerror: a is not defined
typeof a 未报错
console.log(typeof a)// => 'undefined' 这是浏览器的bug,本应报错,因为没有a(暂时性死区)
使用let后:
console.log(typeof a)// => referenceerror: cannot access 'a' before initializationlet a
返回不能在a被定义之前使用它,解决暂时性死区问题。
4. let创建的全局变量没有给window设置对应的属性
首先看带var与不带var创建全局变量时的区别
/* * 不带var的:相当于给全局对象window设置了一个属性a * window.a = 13 */a = 13console.log(a) // => window.a 13/* * 栈内存变量存储空间 * b * 带var的:是在全局作用域下声明了一个变量b(全局变量), * 但是在全局下声明的变量也相当于给全局对象window增加了一个对应的 * 属性b(只有全局作用域具备这个特点) */var b = 14console.log(b)console.log(window.b)
使用let创建时:
/* * 栈内存变量存储空间 * c * 带let的:仅仅在全局作用域下声明了一个变量b(全局变量), * 并未给全局对象window增加对应的属性c */let c = 15console.log(c) // => 15console.log(window.c) // => undefined
5. let会产生块级作用域
下面代码能否实现点击某个按钮,body的背景色改为按钮对应的颜色,若不能,如何改进(腾讯)
<!doctype html><html><head> <meta charset="utf-8"> <meta http-equiv="x-ua-compatible" content="ie=edge"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0"> <style> * { margin: 0; padding: 0; } html, body { height: 100%; overflow: hidden; } button { padding: 5px 10px; cursor: pointer; } </style></head><body><!----><button value="red">红</button><button value="green">绿</button><button value="blue">蓝</button><script> var body = document.queryselector('body'), buttons = document.queryselectorall('button'), arr = ['red', 'green', 'blue'] for (var i = 0; i < buttons.length; i++) { buttons[i].onclick = function () { body.style.background = arr[i] } }</script></body></html>
答案当然是不能,因为通过var定义的变量,在for循环中的i是全局的,变量提升、3次循环过后,i=3,因为点击每个都相当于点击最后一个。
【推荐学习:javascript高级教程】
以上就是javascript中var和let有什么区别的详细内容。
其它类似信息

推荐信息