一道变态的js题
一道腾讯js面试题
题目如下:
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 ?
按网友的描述猜测,这应该是QQ招聘的题目,既考查了ECMAScript知识,又需要被面试者的应用实践,题目本身无标准答案,在不同浏览器下表现不同。
这是一道难度较大,并且出题角度比较刁钻的面试题。
正赶上最近在研究Javascript这部分的内容,便对该题目涉及的考察点进行了更深入的研究。以下给出简单分析。
考察点
对作用域链(scope chain)、执行环境(execution context)、变量对象(variable object)的理解
命名函数表达式,参见这里
以上知识点在不同浏览器(主要为:IE和Firefox)的实现差异
相等操作符的隐式类型转换规则
首先,代码简化为(1):
f = function() {return true;};
g = function() {return false;};
(function() {
alert(g());
function g() {return true;}
})();
上面的例子中,当控制器进入匿名函数的执行环境后,初始化活动对象,函数声明g被放到了执行环境的变量对象集合中,property为g,值为g函数对象,当执行g(),返回true。
将上面的代码稍加改变(2):
f = function() {return true;};
g = function() {return false;};
(function() {
alert(g());
if (true) {
function g() {return true;}
}
})();
上面代码,结果应该与(1)相同,但Firefox处理结果出现了不同返回false,暂且把这看作是Firefox的bug(虽然Firefox不认为这是个Bug)。
分析:在Firefox中,出现在条件语句中的代码块不做活动对象初始化的处理(Firefox把它当作块作用域??),即把上例的if (true) 修改为 if (false) 结果是一样的。
到此为止,已经可以确定g()执行后的值是true还是false了。
整合一下(3):
f = function() {return true;};
g = function() {return false;};
(function() {
if (g()) {
alert("能看到这个警告框,说明你的浏览器不是Firefox");
function g() {return true;}
}
})();
继续分解代码(4):
f = function() {return true;};
g = function() {return false;};
(function() {
f = function() {return false;};
})();
alert(f());
代码运行,无一例外的返回false,这正是我们想要的结果。
然后稍作改变(5):
f = function() {return true;};
g = function() {return false;};
(function() {
f = function f() {return false;};
})();
alert(f());
经过稍加修改后,这次掉链子的轮到IE了,IE竟然返回了true!!!这是IE的Bug
最后大整合。
我们不仅知道结果,而且知道为啥是这结果了(6):
f = function() {return true;};
g = function() {return false;};
(function() {
if (g() && [] == ![]) {
f = function f() {return false;};
function g() {return true;}
}
})();
alert(f());
没有问题的浏览器会返回:false
Firefox不会执行到if条件内部,返回:true
IE会执行到if条件内部(但把if内部的f作为局部变量处理了),最后返回:true
一道变态的js题的更多相关文章
- 没做过编译器就是被人欺——从一道变态的i++题猜编译器的行为(表达式从左往右扫描,同一变量相互影响)
首先不要被人蒙了,如果是这样,根本编译不过: int i=1; int b=i+++++i; printf("%d %d\n", b ,i); Mingw报错:error: lva ...
- 一道js题
<script> var a = 5; function test(){ this.a = 10; a = 15 this.func = function(){ var a = 20 ; ...
- 洛谷P2918 [USACO08NOV]买干草(一道完全背包模板题)
题目链接 很明显的一道完全背包板子题,做法也很简单,就是要注意 这里你可以买比所需多的干草,只要达到数量就行了 状态转移方程:dp[j]=min(dp[j],dp[j-m[i]]+c[i]) 代码如下 ...
- 又一道区间DP的题 -- P3146 [USACO16OPEN]248
https://www.luogu.org/problemnew/show/P3146 一道区间dp的题,以区间长度为阶段; 但由于要处理相邻的问题,就变得有点麻烦; 最开始想了一个我知道有漏洞的方程 ...
- [真题] 一道 vsftp 运维题
一道 vsftp 运维题 一.前言 在 V 站上凑巧看到了好友发的求助帖,五天时间一个理他的都没有.哈哈哈~ 废话不多说,我们来试试. 二.题目 这里我们假设存在这样的场景: 网络内有普通用户 ade ...
- QDUOJ 一道简单的数据结构题 栈的使用(括号配对)
一道简单的数据结构题 发布时间: 2017年6月3日 18:46 最后更新: 2017年6月3日 18:51 时间限制: 1000ms 内存限制: 128M 描述 如果插入“+”和“1”到 ...
- 一道经典JS题(关于this)
项目中碰到的问题,以前也碰到过,没有重视,现记录如下. <input type='button' value='click me' id='btn' /> <script> v ...
- 一道js题(引用类型、基本类型、包装对象、函数赋值)
var a = 1; var obj = { b: 2 }; var fn = function () {}; fn.c = 3; function test(x, y, z) { ...
- C++的一道变态题
题目大概是这样的:有两个数组a[N],b[N],求构造 b[i]=a[0]*a[1]*a[2]*...a[N-1]/a[i], 要求: .不能使用除法. .空间复杂度O(1),时间复杂度O(n). . ...
随机推荐
- 1.Java为什么能跨平台运行?请简述原理
因为它有虚拟机(JVM),JAVA程序不是直接在电脑上运行的,是在虚拟机上进行的,每个系统平台都是有自己的虚拟机(JVM),所以JAVA语言能跨平台. 1, java代码不是直接运行在CPU上,而是运 ...
- JSP基本语法--Page指令 <%@page 属性=”内容“%>
page指令语法:<%@page 属性=”内容“%> 常用:contentType,import,pageEncoding 例子,设置MIME属性,如果使用一些高版本的tomcat,可能自 ...
- cpu、内存、缓存、硬盘使用率
1.cpu ./bunsan2.sh uptime < servers.txt | awk '{print $11 }' |sed 's/,//g' #!/bin/bash cpu_load=$ ...
- nm applet disable
http://support.qacafe.com/knowledge-base/how-do-i-prevent-network-manager-from-controlling-an-interf ...
- thinkPHP16---伪静态
url伪静态通常是为了 满足更好的SEO效果,thinkPHP支持伪静态url设置,可以通过设置URL_HTML_SUFFIX的参数 随意在URL的最后添加你想要的静态后缀,而不会影响当前操作的正常执 ...
- MFC 窗体背景图片设置
很多人在做MFC 界面的时候想要给对话框加入背景图片,很多人都会想到在OnPaint()里面来加一段代码来实现,其实这样做并不怎么科学,因为它会导致窗口不断重绘,在很多项目中窗口会闪烁(比如带播放视频 ...
- L8,the best and the worst
expressions: enter for 报名参加,只有作为参加的意思的时候才会用for enter the room进入房间 a little prize for the worst garde ...
- php获取文件名
php获取文件名$phpself =$_SERVER['PHP_SELF']; //获取当前文件名$str = end(explode("/",$phpself)); //去掉'/ ...
- 转 Android 编程下两种方式注册广播的区别
常驻型广播 常驻型广播,当你的应用程序关闭了,如果有广播信息来,你写的广播接收器同样的能接收到,它的注册方式就是在你应用程序的AndroidManifast.xml 中进行注册,这种注册方式通常又被称 ...
- java dom4j解析xml实例(2)
java利用dom4j解析xml 需要的jar包: dom4j官方网站在 http://www.dom4j.org/ 下载dom4j-1.6.1.zip 解开后有两个包,仅操作XML文档的话把dom4 ...