1 求以下函数的输出

1.1 考察点: 变量提升、this、作用域

// 考察点 作用域、this、变量提升
var a = 10
function test() {a = 100console.log(a)  console.log(this.a) var aconsole.log(a)
}
test()
  • 第一个和第三个肯定是100
  • 在node环境下,没有window的概念,因此输出的是 undefined. (最后答案 100 undefined100)
  • 在浏览器环境下,在没用找到this时,会顺着作用域链找到window,而 window.a =10,因此会输出 10. (最后答案 100 10 100)

[稍微改进]

var a = 10;
function test(){console.log(a);a = 100;console.log(this.a);var a;console.log(a)
}
test();
  • 此时根据与解析,会有如下:
var a = 10;
function test() {// var a;console.log(a);a = 100;console.log(this.a);var a;console.log(a)
}
test();
  • 浏览器环境下因此答案为: undefined 10 100

1.2 考察点: 闭包的作用域

(function(){var a = b = 3;
})()
console.log(b); // 3
console.log(a); // a is not defined
  • 说明: 在非严格模式下面,出现了var a = b = 3,实际上是b=3var a = b
  • 在执行b=3时,JS解释器会自动在当前的全局环境下面挂在一个b属性,值为3
  • 所以会输出b=3a is not defined

1.3 考察点: 事件循环、单线程异步

for(var i=1 ; i<=3; i++){setTimeout(function(){console.log(i)}, 0)
}
  • 答案: 4 4 4
  • JS是单线程异步,当遇到异步函数的时候,会将异步函数添加到异步函数队列中.
  • for是同步任务,因此,优先执行了3次循环,然后再执行3次输出.此时,由于i的值是4 ,故输出 3个4

[变形]:

for(let i = 1; i<=3; i++){setTimout(function(){console.log(i);}, 0);
}
  • 答案: 1 2 3
  • 前面和上面一样的,但执行到输出i的时候, 由于let 创建的变量是块级作用域.
  • 可以看作是把i 同异步函数一起放在一个块中,放入异步函数的队列中.
  • 当时间到了从异步队列中拿出块来执行

1.4 考察点: 作用域 变量提升 形参实参

function fun(n){console.log(n);var n = 456;console.log(n);
}
var n = 123;
fun(n);
  • 根据与解析,函数实际如下
function fun(n){// var n = n;console.log(n);n = 456;console.log(n);
}
var n = 123;
fun(n);
  • 答案为: 123 456

[稍微改进一下]

function fun(){console.log(n);var n = 456;console.log(n);
}
var n = 123;
fun(n);
  • 答案是: undefined 456

[再稍微改进一下]

function fun(){console.log(n);n = 456;console.log(n);
}
var n = 123;
fun(n);
  • 此时没用变量提升,答案是 123 456

[再再稍微改进一下]

function fun(){console.log(fun);fun = 456;console.log(fun);
}
fun();
var fun = 123;
  • 考察函数的提升和变量的提升,等价于,变量提升的速度快于函数提升
var fun = undefined;
var fun = function (){console.log(fun);fun = 456;console.log(fun);
}
fun();
fun = 123;
  • 由于函数的提升比变量的提升慢,因此,在遇到fun()时,会先执行console.log(fun),
  • 此时会输出fun函数
  • 然后fun赋值为456,然后的console.log会输出456
  • 故输出结果为:[Function fun] 456

[再再再稍微改进一下]

function fun(){console.log(fun);fun = 456;console.log(fun);
}
var fun = 123;
fun();
  • 根据 变量提升,改造如下:
var fun = undefined;
var fun = function(){...};
fun = 123;
fun();
  • 执行到fun()时,由于fun是一个变量,因此会报错: fun is not a function

[再再再再稍微改进一下]

var fun = 123;
function fun(){console.log(fun);fun = 456;console.log(fun);
}
fun();
  • 变量提升改造如下:
var fun = undefined;
var fun = function(){...}
fun = 123
fun();
  • 执行到fun()时,由于fun是一个变量,因此会报错: fun is not a function

2. 总结

  • 使用var的时候要特别小心,它有一个变量提升…
  • 函数也存在变量提升,但是它比变量的提升慢

参考

源代码


javascript --- js中的作用域 变量提升相关推荐

  1. JavaScript 中的 Hoisting (变量提升和函数声明提升)

    如何将 函数声明 / 变量 "移动" 到作用域的顶部. 术语 Hoisting(提升) 在很多 JavaScript 博文中被用来解释标识符的解析.其实 Hoisting(提升) ...

  2. 浅聊JavaScript中的Hoisting(变量提升)

    一直有写博客的想法但因为懒惰等各种情况没有付出实际行动,择日不如撞日,那就今天让我给大家简单归纳总结一下JavaScript中的Hoisting(变量提升)吧! 1.对于变量 //variablesc ...

  3. js高级第一章--变量提升,函数提升

    js高级第一章–变量提升,函数提升 文章目录 前言 一.什么是js里的提升? 二.js变量提升 三.js函数提升 四.特殊情况 总结 前言 在js中,最基本的声明方式有三种,即:var,let,con ...

  4. Cookie操作以及如何在js中调用jsp变量

    存Cookie Cookie idCookie = new Cookie("userId", request.getParameter("id"));Cooki ...

  5. Js中的作用域和作用域链

    Js中的作用域和作用域链 前言 阅读本文,请先阅读:Js中的函数相关:创建函数的三种方式.函数的形参和实参.返回值.return.break.continue的区别.重载和arguments.匿名函数 ...

  6. 读取Node.js中的环境变量

    有没有办法在Node.js代码中读取环境变量? 例如,例如Python的os.environ['HOME'] . #1楼 如果要使用在Node.js程序中生成的字符串键(例如var v = 'HOME ...

  7. js变量提升_学习笔记:JS中的作用域和预解析

    知识总结:谢静贤.汤昊 在javascript中作用域是非常重要的,本文将会说明作用域以及我们在工作,以及面试中的一些面试题,如果有不足的地方希望大家可以评论指出来,自己一定会及时的改正错误,避免大家 ...

  8. JavaScript专题(一)变量提升与预编译,一起去发现Js华丽的暗箱操作

    JavaScript之变量与函数提升 相信阅读完<前端进阶系列>的朋友们已经对Js中经典的知识点有所了解.本系列的第一篇选择了一个值得讨论的问题--变量提升,我们会从遇到问题.分析问题.解 ...

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

    根据官方书籍<你不知道的javascript>(上卷)中写道: "函数会首先被提升,然后才是变量". 例子: console.log(foo); function fo ...

最新文章

  1. JavaScript实现permutate Without Repetitions无重复排列算法(附完整源码)
  2. Solution for Lead OPA test error ( add button clicked after cancel button )
  3. 如何使用 HttpReports 监控 .NET Core 应用程序
  4. linux shell之cut命令
  5. 用python画一只可爱的皮卡丘_用python画一只可爱的皮卡丘实例
  6. [html] 常见的浏览器内核都有哪些?并介绍下你对内核的理解
  7. 关于 ls 命令的一个小小的缺陷
  8. Android应用程序线程消息循环模型分析
  9. 微信模板消息发送实例
  10. 黎曼传记资料(2010-04-22 22:17:06)
  11. 数论—乘法逆元—费马小定理
  12. WiFi、ZigBee、BLE用哪个?小米内部是这样选的
  13. 【加密技术】Java加密算法
  14. androidstudio MultiDex慎用
  15. guid主分区表损坏如何处理_GUID格式GPT硬盘引导损坏了怎么修复
  16. 【Bio】基础生物学 - 基因 gene
  17. 苹果电脑如何设置开启远程控制?
  18. 在线教育的内容研发和技术的迭代创新
  19. python模拟行星运动_Java课程设计——模拟行星运动
  20. 【解决The package java.awt is not accessible】

热门文章

  1. jquery上传图片_文件上传三种方式
  2. updatechecker.java_解决ehcache的UpdateChecker问题
  3. 美团科技 Java工程师_美团网java工程师面试都会问哪些问题?
  4. java同步转化成异步_Java 如何把异步调用模拟成同步调用
  5. mysql安全补丁如何处理_3分钟学会mysql数据库的逻辑架构原理
  6. php图片截取后缀,PHP抓取远程图片(含不带后缀的)教程详解
  7. java jai create 方法_使用JAI扩展Java Image的功能
  8. python flask上传文件_Python-Flask-文件上传
  9. Faster R-CNN的安装及测试(Python版本和Matlab版本)
  10. 时区日期处理及定时 (NSDate,NSCalendar,NSTimer,NSTimeZone)