一道变态的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). . ...
随机推荐
- golang vs java
http://programmers.stackexchange.com/questions/83780/how-fast-can-go-go In terms of language design, ...
- Linux教程之配置权限受限制的SFTP
SFTP 在Linux下是一个很方便很安全的文件传输工具,我常常用它在Linux服务器上替代传统的ftp来传输文件.众所周知SFTP账号是基于SSH账号的,默认情况下访问服务器的权限很大,下面的教程就 ...
- QQ登录界面
@property (nonatomic,assign) IBOutlet UITextField *qq; @property (nonatomic,assign) IBOutlet UITextF ...
- .Net配置错误页
1.在web.config中,配置customErrors节,在子节点error中,可以对特定的错误码,进行错误也配置. 配置举例如下: <customErrors mode="Rem ...
- wpf之数据触发器DataTrigger
wpf, 根据绑定的属性的值的不同(数据分类),界面上显示不同的控件(绑定不同类型的属性),可以使用数据库触发器DataTrigger实现这一功能. 实现的效果如下: 首先建立实体类: 更改通知类: ...
- 转 Problem: AnyConnect was not able to establish a connection to the specified secu
不多说直接上问题,在点击连接时,也是能正常连接上输入密码,在输出用户名密码后 连接后,会出现: problem:anyconnect was net able to establish a conne ...
- C++调用com控件方法
转载自:http://blog.csdn.net/haijun286972766/article/details/6273414 最近要求做一个C++调用com组件的DEMO.由于自己对C++并无研究 ...
- 初识Selenium(一)
Selenium入门相关PPT参考网址:http://wenku.baidu.com/view/d1e7d90390c69ec3d5bb7565.html?from=search 内容引用网址:htt ...
- 借助XShell,使用linux命令sz可以很方便的将服务器上的文件下载到本地,使用rz命令则是把本地文件上传到服务器。
rz 是将window文件传到linux服务器上,到执行rz命令的目录 sz 可以将linux文件发送到windows上,可以选择目录. https://www.google.com/ncr 登录一下 ...
- C++文件编程(文件流操作)
给出了比较常见的文件操作,包括二进制文件操作.代码如下: #include<iostream> #include<cstdio> #include<cstring> ...