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

  1、函数声明。 

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

  2、函数表达式。

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

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

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

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

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

function boo(x){
console.log(x); //
}
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函数声明提升的更多相关文章

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

    解析器在向执行环境中加载数据时,对函数声明和函数表达式并非一视同仁.解析器会率先读取函数声明,并使其在执行任何代码之前可用(可以访问).至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真的被 ...

  2. JavaScript 函数声明,函数表达式,匿名函数,立即执行函数之区别

    函数声明:function fnName () {-};使用function关键字声明一个函数,再指定一个函数名,叫函数声明. 函数表达式 var fnName = function () {-};使 ...

  3. Javascript函数声明与函数表达式

    在定义函数时,我们一般使用下面这两种方法: 使用函数声明定义: function sum (a, b) { return a + b; } 使用函数表达式定义: var sum = function ...

  4. 你不知道的JavaScript--Item6 var预解析与函数声明提升(hoist )

    1.var 变量预编译 JavaScript 的语法和 C .Java.C# 类似,统称为 C 类语法.有过 C 或 Java 编程经验的同学应该对"先声明.后使用"的规则很熟悉, ...

  5. Javascript函数声明与函数表达式的区别

    在定义函数时,我们一般使用下面这两种方法: 使用函数声明定义: 1 2 3 function  sum (a, b) {     return a + b; } 使用函数表达式定义: 1 2 3 va ...

  6. JavaScript 变量声明提升

    JavaScript 变量声明提升 一.变量提升的部分只是变量的声明,赋值语句和可执行的代码逻辑还保持在原地不动 二.在基本的语句(或者说代码块)中(比如:if语句.for语句.while语句.swi ...

  7. javascript 函数声明和函数表达式

    定义js函数的方法有两种,1.函数声明 2.函数表达式 这两种方式的区别是:1.函数声明可以先调用后定义(javascript引擎在解释的时候会把所有的函数声明提升)2.函数表达式必须先定义后使用.看 ...

  8. 浅谈JavaScript变量声明提升

    前段时间阿里实习生内推,一面就被刷了,也是郁闷.今天系统给发通知,大致意思就是内推环节不足以了解彼此,还可以参加笔试,于是赶紧再投一次.官网流程显示笔试时间3月31日,时间快到了,开始刷题.网上搜了一 ...

  9. Javascript 函数声明、调用、闭包

    1 # Javascript 函数声明.调用.闭包 2 # 一.函数声明 3 # 1.直接声明.浏览器在执行前,会先将变量和函数声明进行提升. 4 fn(); 5 function fn () { 6 ...

随机推荐

  1. redis中使用 check-and-set 操作实现乐观锁

    WATCH 命令可以为 Redis 事务提供 check-and-set (CAS)行为. 被 WATCH 的键会被监视,并会发觉这些键是否被改动过了. 如果有至少一个被监视的键在 EXEC 执行之前 ...

  2. 关于python中的dir函数

    dir函数用于查看python对象的属性,如果所查看的python对象已经定义了__dir__方法,则使用dir会返回定义的__dir__方法的返回值.如果没有定义__dir__方法,则会从__dic ...

  3. Xamarin.android 重写axml控件

    https://www.cnblogs.com/lonelyxmas/p/5632694.html <Laco: 用来用引指定的控件            android:layout_widt ...

  4. ES6(四)字符串的扩展

    1.字符的表示方式 最早在  \u0000-\uFFFF 之间的字符已经足够使用吗,每个字符占两个字节,超出范围,必须使用双字节形式表达, 即每个字符占四个字节.超出范围的字符,会被解读成  \uXX ...

  5. 房上的猫:经典排序算法 - 冒泡排序Bubble sort

    原理是临近的数字两两进行比较,按照从小到大或者从大到小的顺序进行交换,这样一趟过去后,最大或最小的数字被交换到了最后一位,然后再从头开始进行两两比较交换,直到倒数第二位时结束,以此类推例子为从小到大排 ...

  6. Django__Ready

    Python WEB框架 : DJango : 大而全 flask : 小而精 tornado : 下载DJango : PIP3 INSTALL DJANGO 创建DJango项目 : django ...

  7. Python中将函数作为另一个函数的参数传入并调用

    在Python中,函数本身也是对象,所以可以将函数作为参数传入另一函数并进行调用 在旧版本中,可以使用apply(function, *args, **kwargs)进行调用,但是在新版本中已经移除, ...

  8. DM企业建站系统v201710 sql注入漏洞分析 | 新版v201712依旧存在sql注入

    0x00 前言 本来呢,这套CMS都不想审的了.下载下来打开一看,各种debug注释,排版烂的不行. 贴几个页面看看 感觉像是新手练手的,没有审下去的欲望了. 但想了想,我tm就是新手啊,然后就继续看 ...

  9. Canvas-图片旋转

    Canvas-图片旋转 众所周知canvas是位图,你可以在里面渲染你要的东西,不过你只能操作canvas的属性来进行编辑.就是说你并不能操作画进canvas的东西,例如我在canvas里添加一幅画, ...

  10. 【转载】在Linux下,一个文件也有三种时间,分别是:访问时间、修改时间、状态改动时间

    在windows下,一个文件有:创建时间.修改时间.访问时间.而在Linux下,一个文件也有三种时间,分别是:访问时间.修改时间.状态改动时间. 两者有此不同,在Linux下没有创建时间的概念,也就是 ...