在JavaScript当中,定义变量通过var操作符+变量名。但是不加 var 操作符,直接赋值也是可以的。
例如 : message = "hello JavaScript ! " 即定义了一个全局变量message,并赋值 “Hello JavaScript!”
--《JavaScript高级程序第三版》

如同往日一般,一群人在所谓的技术交流群里面相互斗图着。突然老王莫名的正经起来,在群里发了一道JavaScript的题目,让大家猜一猜这道题的答案。

var foo = 1;
function bar() {
foo = 10;
return;
function foo() {}
}
bar();
console.log(foo); //求控制台输出多少?

看到这到题目之后,立刻不加思索回答了“10”。
首先第一步定义一个全局变量foo = 1,然后函数执行的时候又定义全局变量 foo = 10覆盖了之前的全局变量,return之后,这个函数就直接结束, function foo {}来不及定义。因此控制台输出10;
按照在《高三》上面看到知识点推断,毫无问题,简直完美呀!

【给自己32个赞!】

但是,在把答案发出去之后。本能就感觉这道题不可能这么简单,不正经的群突然讨论正经的代码,肯定会有大坑等着人来跳。一种不好感觉涌上心头,感觉自己又要被打脸了。

赶紧打开编辑器测试一下这段代码,手哆嗦的按下F12.只见控制台下,一个耀眼的1赫然闯入眼帘。啪啪啪!!这脸又被打的,好疼呀!!

【为什么被打脸的总是我!!】

果不其然群里老王马上的在群里否决我的答案,啪的一下打了这张老脸。
不行!这个脸打了得把场子找回来,这个老王接下来肯定会揭晓答案并公布解题思路。得在他公布之前,讲答案和原因给测试出来。

经过简单的测试之后,发现原来是后面的foo,函数提升到最顶端了。所以后面foo = 10中的foo实际上是一个局部变量了。因此后面console.log(foo)时是拿不到bar函数中的局部变量foo = 10,因此只能拿到全局变量foo = 1;所以控制台输出1。

上文代码的另外一种形式:
var foo = 1;
function bar() {
function foo(){}
foo = 10;
return;
// function foo() {} 相当于这行代码提升到最顶部了
}
bar();
console.log(foo);

被抢了风头的老王果断的不服气呀!说我瞎猜扯犊子一厢情愿的,自己随意猜想的。
好的,下面就是开始解释我为什么说函数function foo(){}提升到最顶端。不改动老王的代码,让我们只是加两个console.log测试一下相应的输出结果。

var foo = 1;
console.log("全局变量:foo = " + window.foo)
function bar() {
console.log("此时bar函数中foo =" + foo)
foo = 10;
console.log("bar函数中的变量是" + foo);
console.log("全局变量foo还是:"+window.foo);
return;
function foo() {}
}
bar();
console.log(foo);
浏览器输出结果

通过这里可以证实我的猜想是正确的,function foo(){}直接被提升到bar()函数最顶端,然后后面foo = 10就不是再重新定义全局变量了,这里foo是一个局部变量的角色被定义出现的。因此才没有将全局变量给覆盖,而由于函数外面是不能直接拿到bar函数当中的局部变量foo,因此继续向上寻找到全局变量foo = 1.从而输出1.

这里估计联想能力丰富的小伙伴肯定会举手说,那么函数有提升的现象。那么变量也是否会有提升现象?不错!不错!!这位小伙伴联想的非常正确,学习就要多学会举一反三。

【奖励一朵小红花】

变量提升
var foo = 1;
function bar() {
foo = 10;
return;
var foo //几乎是相同的代码,只是把 function foo 变成了 var foo。变量也是能够提升了的!
}
bar();
console.log(foo); //还是输出1.
思考:

同样的既然变量能够提升,函数声明能够提升。那么谁升的更高呢?

function test(){
console.log(dabang);
function dabang(){};
var dabang;
}
test(); function test1(){
console.log(dabang);
var dabang;
function dabang(){}; }
test1();

控制台输出结果:


【大棒声明的函数那必须升的高!!!】

小结:

1、在JavaScript当中,函数作用域当中。变量和声明函数都能够提升。
2、同样提升的情况下,声明函数提升的更加高!

以上就是鄙人对于JavaScript函数作用域中“提升现象”一点简单理解,欢迎各位的大佬们指导学习。
其实js的编译就是把作用域先声明,作用域里面用到变量统一先在代码执行前分配内存,也就是先声明,function a(){}这个就直接声明了a函数,var a=function(){}这个表达式是在执行前先声明a变量值为undefined,执行到这句才把function赋值进去.

JavaScript 函数作用域的“提升”现象的更多相关文章

  1. 浅谈JavaScript 函数作用域当中的“提升”现象

    在JavaScript当中,定义变量通过var操作符+变量名.但是不加 var 操作符,直接赋值也是可以的. 例如 : message = "hello JavaScript ! " ...

  2. JavaScript的作用域和提升机制

    JavaScript的作用域和提升机制 你知道下面的JavaScript代码执行时会输出什么吗? 1 2 3 4 5 6 7 8 var foo = 1; function bar() {     i ...

  3. (转载)javascript函数作用域和提前声明

    http://www.cnblogs.com/ArthurPatten/p/3274080.html 一些语言如C.java都有块级作用域,即花括号内的每一段代码都具有各自的作用域,而且变量在声明它们 ...

  4. javascript函数作用域和提前声明

    一些语言如C.java都有块级作用域,即花括号内的每一段代码都具有各自的作用域,而且变量在声明它们的代码段之外是不可见的,但是javascript没有块级作用域.javascript使用函数作用域,即 ...

  5. JavaScript 函数作用域和闭包

    函数作用域和闭包  词法作用域   它们在定义它们的作用域里运行,而不是在执行的作用域运行,但是只有在运行时,作用域链中的属性才被 定义(调用对象),此时,可访问任何当前的绑定.   调用对象     ...

  6. javascript函数作用域链之词法作用域

    在开发语言中常见的作用域规则有  块级作用域和词法作用域 作用域 顾名思义就是起作用的区域  定义一变量后 ,可以在此范围作用的区域 一.块级作用域就是用一个块结构分割变量的访问区域  块即{ } 代 ...

  7. javascript函数作用域实践

    在es6之前,JavaScript是没有块级作用域的,只有函数作用域,也就是说是一个function里面定义的变量外面取不到的:而if for是条件判断的语句,不是函数,由于缺少块级作用域,所以条件中 ...

  8. JavaScript函数作用域和声明提前(3.10.1 page.57)

    <h4>3.函数作用域和声明提前</h4> <p> <!--<script type="text/javascript">-- ...

  9. Javascript 函数声明先提升还是变量先提升

    大家都知道js 分为词法阶段 和执行阶段 也知道它是因为var变量和函数声明会提升 但是你知道他们两个谁先提升的吗 测试一下 function test(){ alert(4); } var test ...

随机推荐

  1. C# 使用Epplus导出Excel [1]:导出固定列数据

    C# 使用Epplus导出Excel [1]:导出固定列数据 C# 使用Epplus导出Excel [2]:导出动态列数据 C# 使用Epplus导出Excel [3]:合并列连续相同数据 C# 使用 ...

  2. (8)zabbix监控项item是什么

    什么是item Items是从主机里面获取的所有数据.通常情况下我叫itme为监控项,例如服务器加入了zabbix监控,我需要监控它的cpu负载,那么实现这个方法的东西就叫item item构成 it ...

  3. Ubuntu 下的aegisub安装

    大家用开源的软件用习惯了.推荐大家使用一下字幕编辑软件 分享的是Ubuntu下的安装教程: $ sudo add-apt-repository ppa:djcj/aegisub $ sudo apt- ...

  4. 详解css媒体查询

    简介 媒体查询(Media Queries)早在在css2时代就存在,经过css3的洗礼后变得更加强大bootstrap的响应式特性就是从此而来的. 简单的来讲媒体查询是一种用于修饰css何时起作用的 ...

  5. Python9-装饰器进阶-day12

    wapers方法 def wahaha(): ''' sljfldsjflds :return: ''' print('娃哈哈') print(wahaha.__name__) #查看字符串格式的函数 ...

  6. java中的equals与==的区别

    equals是Object类的公共方法,方法内部是用==实现的.但是很多类都重写了equals方法,例如基本数据类型的封装类和String类,重写后比较的是对象的值或者内容是否相同.而==是比较地址, ...

  7. PAT Basic 1064

    1064 朋友数 如果两个整数各位数字的和是一样的,则被称为是“朋友数”,而那个公共的和就是它们的“朋友证号”.例如 123 和 51 就是朋友数,因为 1+2+3 = 5+1 = 6,而 6 就是它 ...

  8. redis和memcached的优缺点及区别

    1. 使用redis有哪些好处? (1) 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1) (2) 支持丰富数据类型,支持string,li ...

  9. HDU 3480 DP 斜率优化 Division

    把n个数分成m段,每段的值为(MAX - MIN)2,求所能划分得到的最小值. 依然是先从小到大排个序,定义状态d(j, i)表示把前i个数划分成j段,所得到的最小值,则有状态转移方程: d(j, i ...

  10. Java-替换字符串中的子字符串

    自顶一个repace方法 package com.tj; public class MyClass implements Cloneable { public static void main(Str ...