转载http://cymoft.blog.51cto.com/324099/1260099

1
2
3
4
5
6
7
8
9
f = function() {return true;}; 
g = function() {return false;}; 
(function() { 
   if (g() && [] == ![]) { 
      f = function f() {return false;}; 
      function g() {return true;} 
   
})(); 
alert(f()); // true or false ?

此题的关键是第4行的if条件

g() && [] == ![]

这里有三个关键的点,

第一,g()在这里执行的到底是第2行的函数还是第6行的函数?

第二,Javascript里面的falsy值

第三,== 运算符的运算逻辑

先看第一点,我不喜欢卖关子,直接揭晓答案,第4行的g(),执行的是第6行的函数,返回值的是true。

这里的考点是javascript的Execution Context, Variable Object, Scope Chain等概念,简单来说,Javascript的作用域是函数级别的,并且在函数刚开始执行时,就会对函数体内所有的变量及内部函数进行声明,不会等到写的那一行,也就是说,即使你一个内部函数写在包含它的函数的最后面,你在第一行也照样用。回到这道题,我们本来有一个全局的函数g,写在第二行,但是进入第4行,我们进入了一个匿名函数的内部,这个匿名函数里面又在第6行声明一个局部函数g,于是这个局部函数覆盖了全局函数,因此,第4行调用的是写在第6行的局部函数g。

既然g()返回的true,那么接下来就要看 [] == ![] 这句极诡异的比较式的值,这里是拿一个空数组去跟空数组的取反的值比较,初看起来肯定是false啊。可惜,它的值是true,请不要崩溃,让我来仔细分析javascript的操蛋的逻辑。

首先我们看右边的 ![],对一个空数组取反,那么意味着先要把空数组转化为一个boolean值,再取反,在javascript中,所有对象在作为boolean值使用时,都是表示true,空数组也是一个对象,所以空数组也是true,那么对空数组取反,等价于 !true,所以,![]的值为false。

好了,既然右边说完了是false,现在我们就等于在看 [] == false,刚才不是说了空数组是对象是true么,那很明显这个比较就是true == false, 就是返回false对不对?可惜不是,这个比较会返回true,看到这你抓狂了没有,想不通了有没有?先冷静,我来告诉你发生了什么,根据 ECMAScript的对于==的规范,这样一个表达式最终是这么做的

1.把右边的false转成数值0

2.把左边的对象转成字符串,空数组转成字符串就是空字符串

3.把空字符串转成数值,结果是0

4.比较0 == 0,返回true

这里的关键是第2步,数组会先转成空字符串,空字符其实本身就是一个falsy值。

好了,到底谜底全部解开,第4行的if中的判断为实际上是true && true,结果还是true,于是全局函数f在第5行被重新赋值,所以在第9行执行的是第5行被重新赋值的f,返回false。

关于第5行其实还有点小问题,为什么这里的function f() {return false;}没有像第6行的函数g一样被当做一个局部函数,如果这样的话,那么f也是一个局部函数,对f的赋值应该不会影响全局函数f。这里的原因在于,整个第5行不是一个函数声明,第5行作为一个整体其实是一条赋值语句,所以这里的f不会被当做局部变量。

一道变态的Javascript面试题的更多相关文章

  1. 一道简单的JavaScript面试题

    好久没更新博客了,随便写点东西吧. 自从工作之后就特别忙,忙的过程中有时候挺迷茫的,可能是大多数时候写的都是简单的业务代码,很久没好好充电了.最近一直在零碎的上班路上等电梯时间里面学习<图解HT ...

  2. 一道 JavaScript 面试题

    有一道 JavaScript 面试题. f = function () { return true; }; g = function () { return false; }; (function() ...

  3. 学生问的一道javascript面试题[来自腾讯]

    function Parent() { this.a = 1; this.b = [1, 2, this.a]; this.c = { demo: 5 }; this.show = function ...

  4. 你应该知道的25道Javascript面试题

    题目来自 25 Essential JavaScript Interview Questions.闲来无事,正好切一下. 一 What is a potential pitfall with usin ...

  5. 一道变态的js题

    一道腾讯js面试题 题目如下: f = function() {return true;}; g = function() {return false;}; (function() { if (g() ...

  6. 174道 JavaScript 面试题,助你查漏补缺

    最近在整理 JavaScript 的时候发现遇到了很多面试中常见的面试题,本部分主要是作者在 Github 等各大论坛收录的 JavaScript 相关知识和一些相关面试题时所做的笔记,分享这份总结给 ...

  7. 互联网中级Javascript面试题

    互联网中级Javascript面试题 1.实现一个函数clone,可以对JavaScript中的5种主要的数据类型(包括Number.String.Object.Array.Boolean)进行值复制 ...

  8. 互联网公司前端初级Javascript面试题

    互联网公司前端初级Javascript面试题 1.JavaScript是一门什么样的语言,它有哪些特点?(简述javascript语言的特点)JavaScript是一种基于对象(Object)和事件驱 ...

  9. 人人网javascript面试题

    JavaScript面试题要求:以下题目必须从一至四题中,选出三道题,使用原生代码实现,不可使用任何框架,第五题为选作题. 一.  在页面的固定区域内实现图片的展示       <ignore_ ...

随机推荐

  1. idea web项目动态部署

    最近通过idea新创建一个web项目,想让web项目的前后端代码都动态部署.虽然网络上已经有了不少文章,但我自己还是有遇到一些坑,因此总结一下我遇到的坑的经验. 项目的web容器用的是本地的tomca ...

  2. PE格式第六讲,导出表

    PE格式第六讲,导出表 请注意,下方字数比较多,其实结构挺简单,但是你如果把博客内容弄明白了,对你受益匪浅,千万不要看到字数多就懵了,其实字数多代表它重要.特别是第五步, 各种表中之间的关系. 作者: ...

  3. btsync 分享资源

    Btsync是一款跨平台软件,可以在不同的设备之间共享文件. Btsync类似于BT下载,用户对用户(多用户)之间的传送. 文档的分享者可以将资源放到文件夹下,生成共享Key,分享给接受者,接受者只需 ...

  4. Xamarin.Forms 开发IOS、Android、UWP应用

    C#语言特点,简单.快速.高效.本次我们通过C#以及Xaml来做移动开发. 1.开发工具visual studio 2015或visual studio 2017.当然visual studio 20 ...

  5. ELK简介

    什么是ELK ELK是ElasticSearch,LogStash以及Kibana三个产品的首字母缩写.是可以和商业产品 Splunk 相媲美开源项目. 2013 年,Logstash 被 Elast ...

  6. Java常用类(三)之StringBuffer与StringBuidler

    前言 前面一篇给大家介绍了String类,这个我们经常会用到的一个类,那这一篇给大家分享的是StringBuffer与StringBuidler.等下我也会比较他们三个之间的区别 一.StringBu ...

  7. TsBatis 预览

    前言 在发布了 mybatis-dynamic-query之后感觉基本功能稳定了,而且现在在工作项目开发效率大大提高,而且非常易于维护. 最近准备带几个小朋友以前用typescript 打通前后端,当 ...

  8. 【NOIP2016提高组】 Day1 T3 换教室

    题目链接:https://www.luogu.org/problemnew/show/P1850 此题正解为dp. 我们先用floyd处理出任意两个教室之间的距离,用dis[i][j]表示. 用f[i ...

  9. 本地idea调试spark2.x程序

    1.构建使用idea 构建maven 项目 选择org.scala-tools.archetypes:scala-archetype-simple,然后一直点next,maven最好选中本地配置国内源 ...

  10. Yii2之类自动加载

    在yii中,程序中需要使用到的类无需事先加载其类文件,在使用的时候才自动定位类文件位置并加载之,这么高效的运行方式得益于yii的类自动加载机制. Yii的类自动加载实际上使用的是PHP的类自动加载,所 ...