zoukankan      html  css  js  c++  java
  • 一道变态的Javascript面试题

    转载http://cymoft.blog.51cto.com/324099/1260099

    1
    2
    3
    4
    5
    6
    7
    8
    9
    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 ?

    此题的关键是第4行的if条件

    g() && [] == ![]

    这里有三个关键的点,

    第一,g()在这里执行的到底是第2行的函数还是第6行的函数?

    ,Javascript里面的falsy值

    ,== 运算符的运算逻辑

    先看第一点,我不喜欢卖关子,直接揭晓答案,第4行的g(),执行的是第6行的函数,返回值的是true。

    这里的考点是javascript的Execution Context, Variable Object, Scope Chain等概念,简单来说,Javascript的作用域是函数级别的,并且在函数刚开始执行时,就会对函数体内所有的变量及内部函数进行声明,不会等到写的那一行,也就是说,即使你一个内部函数写在包含它的函数的最后面,你在第一行也照样用。回到这道题,我们本来有一个全局的函数g,写在第二行,但是进入第4行,我们进入了一个匿名函数的内部,这个匿名函数里面又在第6行声明一个局部函数g,于是这个局部函数覆盖了全局函数,因此,第4行调用的是写在第6行的局部函数g。

     

    既然g()返回的true,那么接下来就要看 [] == ![] 这句极诡异的比较式的值,这里是拿一个空数组去跟空数组的取反的值比较,初看起来肯定是false啊。可惜,它的值是true,请不要崩溃,让我来仔细分析javascript的操蛋的逻辑。

    首先我们看右边的 ![],对一个空数组取反,那么意味着先要把空数组转化为一个boolean值,再取反,在javascript中,所有对象在作为boolean值使用时,都是表示true,空数组也是一个对象,所以空数组也是true,那么对空数组取反,等价于 !true,所以,![]的值为false。

    好了,既然右边说完了是false,现在我们就等于在看 [] == false,刚才不是说了空数组是对象是true么,那很明显这个比较就是true == false, 就是返回false对不对?可惜不是,这个比较会返回true,看到这你抓狂了没有,想不通了有没有?先冷静,我来告诉你发生了什么,根据 ECMAScript的对于==的规范,这样一个表达式最终是这么做的

    1.把右边的false转成数值0

    2.把左边的对象转成字符串,空数组转成字符串就是空字符串

    3.把空字符串转成数值,结果是0

    4.比较0 == 0,返回true

    这里的关键是第2步,数组会先转成空字符串,空字符其实本身就是一个falsy值。

    好了,到底谜底全部解开,第4行的if中的判断为实际上是true && true,结果还是true,于是全局函数f在第5行被重新赋值,所以在第9行执行的是第5行被重新赋值的f,返回false。

    关于第5行其实还有点小问题,为什么这里的function f() {return false;}没有像第6行的函数g一样被当做一个局部函数,如果这样的话,那么f也是一个局部函数,对f的赋值应该不会影响全局函数f。这里的原因在于,整个第5行不是一个函数声明,第5行作为一个整体其实是一条赋值语句,所以这里的f不会被当做局部变量。

  • 相关阅读:
    POJ3320 Jessica's Reading Problem
    POJ3320 Jessica's Reading Problem
    CodeForces 813B The Golden Age
    CodeForces 813B The Golden Age
    An impassioned circulation of affection CodeForces
    An impassioned circulation of affection CodeForces
    Codeforces Round #444 (Div. 2) B. Cubes for Masha
    2013=7=21 进制转换
    2013=7=15
    2013=7=14
  • 原文地址:https://www.cnblogs.com/icelin/p/3605228.html
Copyright © 2011-2022 走看看