js变量提升及作用域

97 阅读2分钟

注意:表达式函数,是没有函数提升的

作用域

全局作用域:在全局声明的变量或者函数
块级作用域:ES6新推出的作用域,使用letconst进行声明
函数作用域:在函数内部声明的变量或函数

变量提升

// 变量提升:
console.log(a) // undefined
var a = 10;
//为什么a为undefined,执行步骤如下:
var a;
console.log(a)
a = 10;

在上面的题中,我们使用Var声明变量,在执行上下文时,会首先初始化变量,并赋值undefined。

函数提升

// 函数提升
foo() 
function foo(){
    console.log(1)  // 打印结果为1
} 

变量提升和函数提升同时存在

function test(){
    console.log(1,foo);
    console.log(2,bar);
    var foo = 'hello';
    console.log(3,foo);
    var bar = function(){
        return 'world';
    }
    function foo(){
        consloe.log(4,Hello111)
    }
}
test()
// 打印结果由上至下分别是:
// 1 ƒ foo(){
        consloe.log(Hello111)
    }
// 2 undefined
// 3 'hello'
// 4 undefined
// 首先注意:函数提升比变量提升的优先级更高一些
// 执行步骤如下
function test(){
// 函数声明,将函数提到最顶端,
     foo(){
            consloe.log(4,Hello111)
        }
     // 所以,首次打印的时候,结果是foo(){}整个函数
    console.log(1,foo);
    //bar是一个变量被赋值了一个函数,所以这里属于是将bar这个变量提升
    var bar
    // 所以,打印结果为undefined
    console.log(2,bar);
    //var变量提升,
    var foo
    foo = 'hello';
    // 所以打印结果是hello
    console.log(3,foo);
    var bar = function(){
        return 'world';
    }
}
test()

函数和变量名相同的情况

注意: 此情况,函数声明表达式除外

console.log(a);
console.log(a());
var a = 1;
function a(){
    console.log(2)
}
a = 3;
console.log(a)
console.log(a())
// 打印结果
// ƒ a(){
//    console.log(2)
//}
// 2
// undefined
// 3
// Uncaught TypeError: a is not a function
//     at <anonymous>:9:13

//执行步骤
`注意:函数提升比变量提升优先级高`
console.loa(a) //此处打印的是一整个函数
a()
function a(){
    console.log(2)
console.log(a()) //打印出函数内部的结果2
console.log(a) // 变量提升,此时还没有赋值
var a
console.log(a) // undefined
a= 3
console.log(a()) //此时a作为一个变量存在,并不是一个函数,所以报错
// Uncaught TypeError: a is not a function
//     at <anonymous>:9:13