欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

js面试题

程序员文章站 2022-06-01 16:51:45
...
一道腾讯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其他的版本是否是可以的,还请知道的大神解释下?