一、作用域与作用域链
作用域分为全局作用域与局部作用域,局部作用域分为块作用域与函数作用域。
- 全局作用域在网页打开时生效,网页关闭时销毁
- 函数作用域只在函数被调用时产生,运行结束后销毁,每次调用都会产生一个新的作用域。
作用域链:如果使用到一个变量时,会先从当前代码块中寻找,有则用,无则向上层代码块寻找,一直到全局作用域中,如果全局作用域中也没有,报错xx is not defined。
二、变量提升
window对象代表浏览器窗口,通过浏览器提供的window对象可以对窗口进行操作,window还存储了js内置对象(es标准所定义的对象如string、number等等)以及浏览器的宿主对象(浏览器提供对象的如console、alert、document、dom、bom)。
- var不具有块作用域,利用var声明变量都会作为window对象的属性保存
- 使用function声明的函数,都会作为window的方法保存
- 使用let声明的变量不会存储在window,会存在在一个访问不到的地址,如果同时使用window与let声明一个变量,会优先访问let声明的
//变量提升作用:合理进行内存分配,提前预留变量,函数大小,降低内存重新分配次数,提升性能
function fn(){
var a = 10
a = 10 // 在局部变量中如果没有使用var let const 声明变量,则自动变成window的属性,也就是全局变量
}
fn()
console.log("a",a) // var虽然没有块作用域,但是有函数作用域所以结果报错a is not defined
//使用var声明的变量会将声明提前,赋值不提前 、function声明的函数会整体提前运行。可以在声明前访问调用,但是var c = function(){}不可以。
//使用let、const声明的变量实际上也会存在变量提升,但是在赋值之前解释器禁止对该变量访问
var a = 1
function fn(){
console.log(a) //undefinde ,var变量提升
var a = 2
console.log(a) //2 局部变量
}
fn()
console.log(a) //1 全局变量
//函数中定义了形参就相当于在函数体内定义了对应变量,但是没有赋值。参数也属于局部变量
var a = 1
function fn(a){
console.log(a) //undefinde ,形参定义
a = 2
console.log(a) //2 给形参定义的a赋值2(局部变量)
}
fn()
console.log(a) //1 全局变量
//传递实参
var a = 1
function fn(a){
console.log(a) //10 ,形参定义
a = 2
console.log(a) //2 给形参定义的a赋值2(局部变量)
}
fn(10)
//传递变量
var a = 1
function fn(a){
console.log(a) //1
a = 2 //对局部变量a进行赋值,不影响全局变量
console.log(a) //2 给形参定义的a赋值2(局部变量)
}
fn(a) //传递的时var声明的a的值
console.log(a) //1 全局变量