在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函数作用域中“提升现象”一点简单理解,欢迎各位的大佬们指导学习。

ps:打脸也是可以的,毕竟错了就是错了。(那是打脸可否轻一点,留着日后再打呀!(~ ̄▽ ̄)~)



【吾虽浪迹天涯,却从未迷失本心!吾虽恶搞不断,却不敢胡乱代码!】

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

  1. 浅谈javascript函数节流

    浅谈javascript函数节流 什么是函数节流? 函数节流简单的来说就是不想让该函数在很短的时间内连续被调用,比如我们最常见的是窗口缩放的时候,经常会执行一些其他的操作函数,比如发一个ajax请求等 ...

  2. [转载]浅谈JavaScript函数重载

     原文地址:浅谈JavaScript函数重载 作者:ChessZhang 上个星期四下午,接到了网易的视频面试(前端实习生第二轮技术面试).面了一个多小时,自我感觉面试得很糟糕的,因为问到的很多问题都 ...

  3. 浅谈javascript函数,变量声明及作用域

    javascript函数跟变量的声明.作用域这些概念网上都已经讲烂了. 这里写个博客,也相当于做个笔记. 变量声明 首先看个例子: var globalVar = "gv"; fu ...

  4. 浅谈JavaScript的作用域

    前段时间学了下JavaScript作用域,这个东西在JavaScript非常重要,也是JavaScript很基础的东西,正如少林里面基础武功,有了基础,才能学绝世武功. 作用域的作用是啥?一套设计良好 ...

  5. [转]浅谈javascript函数劫持

    转自:Ph4nt0m Security Team 这么多年了,现在学习依然还是有很多收货,向前辈致敬.转载一方面是自己存档一份,另一方面是让更多喜欢安全的人一同学习. ================ ...

  6. 浅谈javascript函数执行过程

    javascript函数执行过程: 1. 为函数创建一个执行环境 2. 复制函数的 [[scopes]] 属性中的对象构建起执行环境的作用链域 3. 创建函数活动对象并推入执行环境作用链域的前端 4. ...

  7. 浅谈JavaScript函数

    JavaScript作为一种基于对象(非严格面向对象)的语言,函数在JS中的地位非同一般:用函数声明类和对象.甚至函数本身也是对象. 一.函数的三种声明方式辨析. 1.function命令 funct ...

  8. 浅谈JavaScript函数重载

    上个星期四下午,接到了网易的视频面试(前端实习生第二轮技术面试).面了一个多小时,自我感觉面试得很糟糕的,因为问到的很多问题都很难,根本回答不上来.不过那天晚上,还是很惊喜的接到了HR面电话.现在HR ...

  9. JavaScript 函数作用域的“提升”现象

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

随机推荐

  1. Java+Selenium自动化对非输入框的日历或日期控件的处理

    如图:          1.问题描述: 在应用selenium实现web自动化时,经常会遇到处理日期控件点击问题,手工很简单,可以一个个点击日期控件选择需要的日期,但自动化执行过程中,完全复制手工这 ...

  2. 每日一练ACM 2019.0416

    2019.04.16     Problem Description Your task is to Calculate the sum of some integers.   Input Input ...

  3. jsonp 简单封装

    import originJSONP from 'jsonp' // 引入 jsonp 模块 // 对外暴露方法 jsonp // 通常传给服务端的 url 地址带参数 设计目的是希望有纯净的 url ...

  4. 扁平化promise调用链(译)

    这是对Flattened Promise Chains的翻译,水平有限请见谅^ ^. Promises对于解决复杂异步请求与响应问题堪称伟大.AngularJS提供了$q和$http来实现它:还有很多 ...

  5. vue的指令

    我之前学了学angular 发现angular和vue的指令有点类似 先说一下 new  Vue({          el: "#box", // element(元素) 当前作 ...

  6. centos 7 默认图形界面(或者字符界面)启动

    1.切换到管理员用户 2.systemctl get-default命令获取当前模式(可以省去) 3.systemctl set-default graphical.target 修改启动模式(修改为 ...

  7. Oracle EBS数据定义移植工具:Xdf(XML Object Description File)

    转载自:http://www.orapub.cn/posts/3296.html Oracle EBS二次开发中,往往会创建很多数据库对象,如表.同义词.视图等,这些数据库对象是二次开发配置管理内容很 ...

  8. asp.net中的Filter类型其实是被当作单例的

    Filter对请求进行过滤.例如,在进行身份验证的基础上增加一些权限判断,对于身份验证通过的用户,检测其是否有开通UserSpace,如果没有则在Response中说明.示例代码如下: public ...

  9. PYTHON黑帽编程 4.1 SNIFFER(嗅探器)之数据捕获--补充

    荒废了一个多月了,重新捡起来,手生了不少.发现在<4.1下>的文章里没有 提到pcap库,实在是不应该. 在网络数据分析的工具中,tcpdump绝对是大名鼎鼎,tcpdump底层是libp ...

  10. 【设计经验】2、ISE中ChipScope使用教程

    一.软件与硬件平台 软件平台: 操作系统:Windows 8.1 开发套件:ISE14.7 硬件平台: FPGA型号:XC6SLX45-CSG324 二.ChipScope介绍 ChipScope是X ...