Loading

javascript 作用域、预解析、变量提升

javascript 作用域与预解析

函数的 arguments 对象:

当一个函数不确定传入的行参数量时,可以使用 arguments 这个函数内置的对象来获取到所有的传入参数。arguments 是一个类似数组的集合类型数据结构(伪数组)。所有函数都内置一个arguments 对象,这个对象存储了所有的函数实参。

作用域

全局作用域:

在整个script标签或js文件都生效。

局部作用域:

函数内部声明的变量是局部作用域。如果在函数内部没有声明变量直接使用,那么变量存在隐式声明,隐式声明的变量是全局变量。

执行效率:

  • 全局变量只有浏览器关闭才销毁,比较占用内存资源。
  • 局部变量程序执行完就会销毁,更节约资源。

块级作用域:

被 {} 包裹 使用 let cont 声明的变量就是块级作用域。 (ES6)

作用域链:

代码在执行时,会先在当前作用域查找变量如果没有找到会从上级作用查找,层层查找直到最外层的全局作用域。

预解析

预解析就是JS引擎会把变量和函数声明放到当前作用域最前面,变量只声明不赋值。

var a = 10
fn()
function fn(){
   console.log('打印', a )
    var a = 20
    console.log('打印', a)
}
// 打印 undefined
// 打印 20
// 在全局作用域a变量被提升,在fn函数的局部作用域a变量也被提升,此时的fn函数中的a变量只有申明没有值, 第二次打印fn函数中的a已经被赋值,所以打印的结果是20
function fn(){
    var a = b = c = 5
    console.log('打印', a, b, c)
}
fn()
console.log('打印',  b, c)
// 打印 5 5 5
//  a is not defined

// 这里使用了多个等号赋值实际等同于 var a = 5  b = 5 c = 5
// 只有a变量声明了,而b和c没有声明直接赋值,没有声明的变量会被隐式声明为了全局变量。
// 因此第一次打印 a、b、c的值都是5
// 在函数下面打印的 a 由于没有声明会报错,如果去掉a再打印 b、c都是5
var a = 5
function a(){
    return 6
}
console.log('打印', a )
// 打印 5
// 变量a和函数a都声明并赋值了,由于函数比变量的提升优先级高一些,函数a先提升,变量a后提升,变量a赋值的时候覆盖了函数a,因此打印为 5
function a(){
    return 6
}
var a = 5
console.log('打印', a )
// 打印 5
// 与上面一个例子相同,函数a预解析提升之后比变量a考前,变量a在后覆盖了函数a
console.log('打印', a )
function a(){
    return 6
}
var a = 5
// 打印 [Function: a]
// 在申明和赋值之前打印,函数a和变量a都提升,此时函数a靠前,而变量a此时还没有赋值,因此打印 为 [Function: a]
console.log('打印', a )
var a = 5
function a(){
    return 6
}
// 打印 [Function: a]
// 上面案例相同
var a = 5
console.log('打印', a )
function a(){
    return 6
}
// 打印 5
// 函数a和变量a都提升到了最前,此时a被赋值为5,覆盖了预解析时的值,因此打印为5

var a = 5
function a(){
    return 6
}
console.log('打印', a )
// 打印 5
function a(){
    return 6
}
var a = 5
console.log('打印', a )
// 打印 5
不管函数a声明在前还是在后,由于预解析后都比变量a提升的更靠前一些,a变量靠后赋值时覆盖了函数a的值因此都打印为5
posted @ 2020-03-17 15:31  fsdffsdf  阅读(190)  评论(0编辑  收藏  举报