var定义的函数和变量都会成为window的方法。
let,const的顶级声明不会定义在全局上下文中,但在作用域链解析上效果是一样的。
var str = 'varStr'
console.log(str) // varStr
console.log(window.str) // varStr
let str1 = 'str'
console.log(str1) // str
console.log(window.str1) // undefined
var/let/const的区别及使用场景
var
-
var定义的变量会预解析,
简单的说就是如果变量没有定义就直接使用的话,JavaScript回去解析这个变量,代码不会报错,只会输出undefined
console.log(a) var a = 1 // undefined -
var定义的变量可以反复去定义,当然后面的会覆盖前面的
var a = 1 var a = 2 console.log(a) //2 -
var在循环中使用的时候,循环体外依然可以使用
for(var i = 0 ;i<5;i++){ console.log(i) } console.log(i) //5 -
在循环绑定事件过程中,var定义的变量无法保存,循环会在瞬间执行完
记住这是小bug
var arrLi = document.getElementsByTagName('li') for(var i=0;i<arrLi.length;i++){ arrLi[i].onclick = function () { console.log(arrLi[i])// undefined } } -
var 的声明作用域 函数作用域
在函数内部定义一个var ,函数退出后就被销毁
let
-
let定义的变量不会预解析,必须先声明再使用,否则会报错
console.log(a)// ReferenceError: Cannot access 'a' before initialization let a = 1 -
let不能定义已经定义过的变量(无论之前是用var定义的还是let或者const定义的)
var a = 1 let a = 2 console.log(a) //Uncaught SyntaxError: Identifier 'a' has already been declared -
let是块级作用域,函数内部使用let定义后,对函数外部无影响,简单说就是在一个{}里面生效
for(let i = 0 ;i<5;i++){ console.log(i) } console.log(i) //err -
4,由于let是块级作用域,在循环绑定事件过程中let会在这个循环中生效,再次循环时let会重新定义生效 块作用域是函数作用域的子集
var arrLi = document.getElementsByTagName('li') for(let i=0;i<arrLi.length;i++){ arrLi[i].onclick = function () { console.log(arrLi[i]) } }
const
-
const定义的变量不会预解析,必须先声明再使用,否则会报错
console.log(a) const a = 1 // ReferenceError: Cannot access 'a' before initialization -
const定义的变量不允许修改 let 定义的是可以修改的
const a = 1 console.log(a) a = 5 //TypeError: Assignment to constant variable.-
但是在数组里面,const的值是允许被修改的,这是因为const存储的是地址,值的内容可以变化
const arr1 = [1,2,3,4,5] arr1[3] = 100 console.log(arr1) //[ 1, 2, 3, 100, 5 ]
-
所有 总结就是
一般变量不变的 用const
for循环中用 let
反复定义用 var