JavaScript学习之变量提升与函数提升

135 阅读2分钟

变量提升

ES6之前是没有块级作用域的(也就是 {} ),只有全局作用域和函数作用域,所以变量和函数的定义会提升到当前作用域顶部。

例子1

  function fn()
        {
            console.log( a )
            var a = 10;
            console.log( a )
        }
        fn()

输出结果:

上面的例子其实相当于:

function fn()
        {
            var a
            console.log( a )
            var a = 10;
            console.log( a )
        }
        fn()

var定义的变量会将声明提升到当前作用域的顶部。

例子2

	// 全局变量:全场可用的变量,任何一个地方都可以访问到		
	var a = 20
        function fn()
        {
            console.log( a )
          //局部变量,会提升到当前作用域的顶部,也就是 fn函数的顶部
            var a = 10;
            console.log( a )
        }
        fn()
// 函数内定义的变量a 与 全局定义的变量 a 互不干扰,因为作用域不同,
// 全局变量虽然可以再函数内用,但是函数内部定义了一个同名的,当然要用函数内部自己亲生的
        console.log( a )

结果:

函数提升

函数的声明也会提升到当前作用域最顶部,且优先级比变量的声明高。

函数创建的方式有两种:1、函数声明形式,2函数表达式形式 。且只有函数声明形式可以有变量提升。

什么是函数提升?

举个例子

        fn()
        function fn()
        {
            console.log( a )
            var a = 10;
            console.log( a )
        }

结果:

函数表达式形式则不行,举个例子

        console.log( fun )
        var fun = function ()
        {
            console.log( 'fun' )
        }

结果:

函数表达式形式就相当于变量的提升,只是定义了一下 var fun;

再举个例子

        console.log( fn ) // ƒ fn(){console.log( 'fn' )}
        fn()
        var fn = 123
        function fn()
        {
            console.log( 'fn' )// 'fn'
        }
        console.log( fn ) // 123
        fn = 789
        console.log( fn ) // 789
        console.log( fn() ) //  Uncaught TypeError: fn is not a function

相当于:

  // 函数提升,优先级高于变量提升
			var fn = function ()
        {
            console.log( 'fn' )
        }
      // 变量提升,变量声明并不会覆盖同名函数的提升,但是只要一赋值就会覆盖
        var fn
        console.log( fn )
        console.log( fn() )
	// 变量赋值,覆盖同名函数
        fn = 123
        console.log( fn )
        fn = 789
        console.log( fn )
        console.log( fn() )