一道变态的Javascript面试题
转载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面试题的更多相关文章
- 一道简单的JavaScript面试题
好久没更新博客了,随便写点东西吧. 自从工作之后就特别忙,忙的过程中有时候挺迷茫的,可能是大多数时候写的都是简单的业务代码,很久没好好充电了.最近一直在零碎的上班路上等电梯时间里面学习<图解HT ...
- 一道 JavaScript 面试题
有一道 JavaScript 面试题. f = function () { return true; }; g = function () { return false; }; (function() ...
- 学生问的一道javascript面试题[来自腾讯]
function Parent() { this.a = 1; this.b = [1, 2, this.a]; this.c = { demo: 5 }; this.show = function ...
- 你应该知道的25道Javascript面试题
题目来自 25 Essential JavaScript Interview Questions.闲来无事,正好切一下. 一 What is a potential pitfall with usin ...
- 一道变态的js题
一道腾讯js面试题 题目如下: f = function() {return true;}; g = function() {return false;}; (function() { if (g() ...
- 174道 JavaScript 面试题,助你查漏补缺
最近在整理 JavaScript 的时候发现遇到了很多面试中常见的面试题,本部分主要是作者在 Github 等各大论坛收录的 JavaScript 相关知识和一些相关面试题时所做的笔记,分享这份总结给 ...
- 互联网中级Javascript面试题
互联网中级Javascript面试题 1.实现一个函数clone,可以对JavaScript中的5种主要的数据类型(包括Number.String.Object.Array.Boolean)进行值复制 ...
- 互联网公司前端初级Javascript面试题
互联网公司前端初级Javascript面试题 1.JavaScript是一门什么样的语言,它有哪些特点?(简述javascript语言的特点)JavaScript是一种基于对象(Object)和事件驱 ...
- 人人网javascript面试题
JavaScript面试题要求:以下题目必须从一至四题中,选出三道题,使用原生代码实现,不可使用任何框架,第五题为选作题. 一. 在页面的固定区域内实现图片的展示 <ignore_ ...
随机推荐
- Java—Day5课堂练习
package com.lovo.classes;import java.util.Scanner;public class day5Test { public static void main ...
- Redis 学习笔记-应用场景
Redis作缓存系统 Redis可以对每个键设置生存时间 可以限定数据占用的最大内存空间,在数据达到空间限制后可以按照一定规则自动淘汰不需要的键. 设置方法: 修改配置文件的maxmemory参数,限 ...
- js的事件循环绑定和jQuery的隐式迭代
js的事件循环绑定和jQuery的隐式迭代 js事件循环绑定 jQuery隐式迭代 先举一个例子:给定一个ul,点击列表内的每一个li元素,使它的背景色变红,下边分别用js代码和jQuery实现. & ...
- 【ASP.NET MVC 学习笔记】- 07 使用 Entity Framework
本文参考:http://www.cnblogs.com/willick/p/3304534.html 1.ORM(Object Relation Mapping)工具,是为了解决“关系数据库”和“面向 ...
- Yii2之mailer的使用
Mailer组件是yii框架自带的用于收发邮件的组件,无需安装,只需做一些配置即可使用,非常便捷.本文就mailer组件从配置到使用进行简单讲解. 首先在config/main.php配置如下: ...
- Linux系列教程(五)——Linux链接命令和权限管理命令
前一篇博客我们讲解了Linux文件和目录处理命令,还是老生常淡,对于新手而言,我们不需要完全记住命令的详细语法,记住该命令能完成什么功能,然后需要的时候去查就好了,用的多了我们就自然记住了.这篇博客我 ...
- 2.动手实操Apache ZooKeeper
Tips 做一个终身学习的人! 日拱一卒,功不唐捐. 在本节中,我们将讲解如何下载并安装Apache ZooKeeper,以便我们可以直接开始使用ZooKeeper. 本部分旨在通过提供详细的安装和使 ...
- 双十一临近,怎样让买家流畅地秒杀? ——腾讯WeTest独家开放电商产品压测服务
WeTest 导读 十一月临近,一年一度的电商大戏"双十一"又将隆重出场,目前各大商家已经开始各类优惠券的发放,各类大促的商品表单也已经提前流出,即将流入各个用户的购物车中. 作为 ...
- 变量值a交换b,b交换a....
package day01; public class Test1 { public static void main(String[] args) { //不利用其它变量时期A和B的值交换 Inte ...
- 安装mayavi和VTK库的血泪史
一开始安装VTK库是从官网上下载,但是怎么都找不到whl文件,只有exe文件(vtkpython-7.1.1-Windows-64bit.exe).下载安装之后再PyCharm中import vtk出 ...