一道腾讯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 ?
对作用域链(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。
这个应该可以理解,内部闭合作用域下g()实际调用的是内部定义的方法。
将上面的代码稍加改变(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) 结果是一样的。
ps:58.xx 版本的谷歌下直接显示g() 未定义直接js报错了 (Uncaught TypeError: g is not a function)
到此为止,已经可以确定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,参见:
http://www.w3help.org/zh-cn/causes/SJ9001
至于[]==![]的结果,参考《Javascript类型转换规则》
typeof([])是个object typeof(![])就成了Boolean
alert([])是个空 alert(![]) 是个false javascript中一切空或者0在做比较的时候都会转化成boolean值false所以 答案很明显了 false equals false
楼上的答案不标准,也可以说有些错误。
执行类型转换的规则如下:
如果一个运算数是 Boolean 值,在检查相等性之前,把它转换成数字值。false 转换成 0,true 为 1。
如果一个运算数是字符串,另一个是数字,在检查相等性之前,要尝试把字符串转换成数字。
如果一个运算数是对象,另一个是字符串,在检查相等性之前,要尝试把对象转换成字符串。
如果一个运算数是对象,另一个是数字,在检查相等性之前,要尝试把对象转换成数字。
在比较时,该运算符还遵守下列规则:
值 null 和 undefined 相等。
在检查相等性时,不能把 null 和 undefined 转换成其他值。
如果某个运算数是 NaN,等号将返回 false,非等号将返回 true。
如果两个运算数都是对象,那么比较的是它们的引用值。如果两个运算数指向同一对象,那么等号返回 true,否则两个运算数不等。
最后大整合。
我们不仅知道结果,而且知道为啥是这结果了(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
ps:58.xx 版本的谷歌下直接显示g() 未定义直接js报错了 (Uncaught TypeError: g is not a function)
不清楚是不是很老的问题了,google chrome其他的版本是否是可以的,还请知道的大神解释下?