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 ? 

对作用域链(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.cn-cuckoo.com/main/wp-content/uploads/2009/12/named-function-expressions-demystified.html#named-expr

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其他的版本是否是可以的,还请知道的大神解释下?

你可能感兴趣的:(js面试题)