var定义的变量为函数作用域:
var nub = 1 //全局作用域(window)
function arr() {
var b = 20 //函数作用域arr
if (b === 20) {
var c = 2 // 函数作用域arr,并不是if块
d = 40 // 全局作用域,未加var定义的变量为全局作用域
}
}
变量提升
在代码执行前、解析器会解析代码。
console.log(a)
var a = '输出'
// 结果是undefined 代码执行顺序⬇️
// var a
// console.log(a)
// a = '输出'
哪怕代码中出现不执行的代码、解析器也会执行解析⬇️
funciton hd() {
if (false) {
var web = '本不应该输出的'
}
console.log(web)
}
// 结果是undefined
// 代码中的web还是被提升了,也还是被定义了。但是并未赋值
当发生重名的函数时,后者取代前者,并且函数的优先级别大于变量
var a = 1
function a () {}
console.log(a)
// function a(){}
//因为在变量提升的过程中,遇到相同的函数和变量名称不论前后。函数都是第一位,也就是函数是js的一等公民。
let、const声明、临时死区
意思就是如果声明的变量在使用之后就会报错,必须在使用之前。
并且let和const生命的变量不会注册到全局上。而var生命的变量会挂在window上
console.log(a)
let a = 11
// 输出会报错 Cannot access 'a' before initialization at script 1:13"
let为块级作用域、用let和const生命的变量不会污染的到全局。
let/const声明的变量存在scope里。而var是存在window里的
var**、let、const的共同点**
1、函数中是可以访问全局变量的。
2、作用域内的变量优先使用作用域内的变量。
块作用域
var没有块作用域、会影响全局
var i = 99
for (var i = 0; i<5; i++) {
console.log(i)
}
console.log(i)
// 输出5
因为循环后的i、会影响全局的i
let和const是块级作用域不会影响全局作用域。
const**一探究竟**
const常量在同一个作用域是不可以修改的、但是对象在任何作用域是可以修改的。
只要不改变引用的内存地址就可以修改const
const ITEM = {}
ITEM.config = 1
变量冻结
Object.freeze当用const定义引用类型时、对象内部的参数是可以冻结的。
const list = {
name: 'qihuanran',
age: 12
}
Object.freeze(list) //冻结内部的变量、不允许修改
console.log(list)
传值和传址
传值是新开一块栈内存,并且赋值一份a
传址是新开一快内存,并且指向a,a和b共同使用一块堆内存。
**