zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    观望Java-03:面向对象
    观望Java-02:基础语法
    观望Java-01:Java简介
    组件化开发——组件生命周期
    pug模板引擎——jade
    解决eclipse调试程序时source not found的问题
    Android中设置中文粗体的方法
    svn中编辑log message
    TortoiseSVN使用
    用TorToiseGit来管理github上的项目
  • 原文地址:https://www.cnblogs.com/jf-67/p/8036966.html
Copyright © 2011-2022 走看看