JavaScript函数声明提升

Posted 心欲无痕

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript函数声明提升相关的知识,希望对你有一定的参考价值。

  首先,javascript中函数有两种创建方式,即函数声明、函数表达式两种。

  1、函数声明。 

function boo(){
    console.log(123);
}
boo()

 

  2、函数表达式。

var boo = function(){
    console.log(123)
}
boo()

 

  现在来说说函数声明提升。还是以例子来说明吧。

boo(123)
function boo(x){
    console.log(x); // 123
}

  运行后可知,在函数声明中,函数创建前就可以先调用函数。

  由于函数声明提升,其实上述语句相当于这样:

function boo(x){
    console.log(x); // 123
}
boo(123)

 

  而在函数表达式中,则会是另一番结果。

hoo(456)
var hoo = function(y){
    console.log(y) // Uncaught TypeError: hoo is not a function
}

  运行后,发现会报错,为什么呢?这是因为在函数表达式中,函数声明并不会提前,它只是变量会提升而已。所以上述语句相当于

var hoo;
hoo(456);
hoo = function(y){
    console.log(y) // Uncaught TypeError: hoo is not a function
}

 

  讲到函数声明提升与变量声明提升,这里来举另外一个例子。

var foo = function(){
    console.log(123)
}

function foo(){
    console.log(456)
}
foo()  

  最初我一看到这个,毫不犹豫的就说这个结果是456,然而很遗憾,是错的。下面来分析一下,虽然两个函数的函数名是一样的,但是第一种方法是函数表达式,第二种是函数声明,鉴于变量声明提升和函数声明提升,所以上述语句其实相当于:

var foo;  // 变量声明提升
function foo(){  // 函数声明提升
    console.log(456)
}
foo = function(){  //  变量赋值依然保留在原来位置
    console.log(123)
}
foo() 

  所以结果显而易见,是123喽。

 

  最后补一个容易混淆的。

function Foo(){
    getName = function(){
        console.log(1);
    }
    return this;
}
Foo.getName = function(){
    console.log(2)
}
Foo.prototype.getName = function(){
    console.log(3)
}
var getName = function(){
    console.log(4)
}
function getName(){
    console.log(5)
}
Foo.getName();  // 2
getName(); // 4
Foo().getName(); // 1 foo()执行完成后,将全局的getName也就是window.getName给更改后返回this,而在这里this执行的就是window,所以最后执行的就是window.getName,所以输出1
getName(); // 1 上面已经更改全局的getName,所以依然是1
new Foo.getName(); // 2 new 操作符在实例化构造器的时候,会执行构造器函数,也就是说,foo.getName会执行,输出2
new Foo().getName(); // 3 先new foo()得到一个实例,然后再执行实例的getName方法,这个时候,实例的构造器里没有getName方法,就会执行构造器原型上的getName方法
new new Foo().getName() // 3

 

以上是关于JavaScript函数声明提升的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript 函数声明与函数表达式的区别 函数声明提升(function declaration hoisting)

JavaScript 变量提升,函数提升

JavaScript 变量提升,函数提升

JavaScript 变量声明提升

JavaScript 预解析

JavaScript学习手册(55)