js变量提升,执行顺序,变量声明优先级

1,723 阅读2分钟

1、js变量提升

变量提升:函数声明和变量声明总是会被解释器悄悄地被"提升"到方法体的最顶部。

console.log(param)
// Uncaught ReferenceError
console.log(param)
var param = 2
// undefined

对比两个代码就能体会到变量提升了,其中第二段代码执行顺序是这样的。

var param
console.log(param)
param = 2

2、语句执行顺序

由于变量提升,所以语句的执行顺序是先执行声明语句,然后执行其他语句表达式(表达式就是语句的一种)。直接说声明语句和表达式好像太抽象,先来具化一下。

var a                // 变量声明
function a(){}       // 函数声明

a = function a(){}   // 表达式
a = 2                // 表达式 

语句和表达式的区别

3、出现同名的情况下,变量声明优先级

  • 函数声明优先于变量声明
  • 后执行的函数声明会覆盖之前的函数声明
function a() {}
var a
// a 
// a() {}

var b
function b() {}
// b
// b() {}

4、举一把🌰🌰…

先做套题~

first blood (不想动脑)

(function() {
    var x=foo();
    var foo=function foo() {
        return "foobar"
    };
    return x;
})();

double kill (放弃思考)

alert(fn)
alert(fn())
function fn() {return fn}
alert(fn())
alert(a)
alert(a())
function a(){return fn}
var a = 3
alert(a)
alert(a())

triple kill (我要答案)

fn()
alert(a) 
var a = 0 
alert(a)
function fn () {a=1}

quadra kill (求给答案)

fn()
fn()()
var a= 0
function fn () {
  alert(a)
  var a = 3
  function c () { 
    alert(a)
  } 
  return c
}

penta kill (看答案)

var a = 3
fn(5)
function fn (a) { 
  function a () {} 
  alert(a)
}

解析:

题1解析

(function() {
    var x=foo()
    var foo=function foo() {
        return "foobar"
    }
    return x
})()

()是一个函数表达式,在最外层并没有函数声明
()()是一个语句

执行顺序:
(
    function() {
        var x
        var foo
        
        x = foo()
        foo = function foo(){return 'foobar'}
        return x
    }
)()
// x    Uncaught TypeError foo not a function

题2解析

alert(fn)
alert(fn())
function fn() {return fn}
alert(fn())
alert(a)
alert(a())
function a(){return fn}
var a = 3
alert(a)
alert(a())

执行顺序:
function fn() {return fn}
function a() {return fn} //优先于var a
var a

alert(fn) // function fn() {return fn}
alert(fn()) // function fn() {return fn}
alert(fn()) // function fn() {return fn}
alert(a) // function a() {return fn}
alert(a()) // function fn() {return fn}
a = 3
alert(a) // 3
alert(a()) // Uncaught TypeError foo not a function

题3解析

fn()
alert(a) 
var a = 0 
alert(a)
function fn () {a = 1}

执行顺序:
var a
function fn () {a = 1}

fn() //执行了a=1
a = 1
alert(a) // 1
a = 0
alert(a) //0

题4解析

fn(); 
var a= 0; 
function fn () {
  alert(a); 
  var a = 3; 
  function c () { 
    alert(a); 
  } 
  return c; 
}

执行顺序:
var a
function fn () {
    var a
    function c () {
        alert(a)
    }
    alert(a)
    a = 3
    return c
}
fn()
fn()()

fn():
var a
function c () {
    alert(a)
}
alert(a) // undefined
a = 3
return function c () { alert(a) }
// function c () { alert(a) }

fn()():
fn()
c()
// undefined 
// 3

题5有一点点特殊

var a = 3
fn(5)
function fn (a) { 
  function a () {}
  alert(a)
}

执行过程:
var a
function fn (a) {
    var a
    function a () {}
    alert(a)
}
a = 3
fn(5)
// function a () {}