• 一道 JavaScript 面试题


    有一道 JavaScript 面试题。

    f = function () { return true; };
    g = function () { return false; };
    
    (function() {
        if (g() && [] == ![]) {
            f = function () { return false; };
            function  g() { return true; }
        }
    })();
    console.info(f());

    首先看前两行

    var f = function () { return true; };
    var g = function () { return false; };

    这两行定义了两个变量,而不是函数定义,变量是可以重新赋值的。

    第四行就比较有趣了

    (function () {
        if (g() && [] == ![]) {
            f = function () { return false; };
            function g() { return true; }
        }
    })();

    在 if 条件中调用了函数 g(),但是,这个 g 是第二行定义的函数 g 吗?答案是否定的,因为在匿名函数中又定义了函数 g,局部的定义覆盖了外部的定义,所以,这里调用的是内部函数 g,返回为 true。第一个条件通过,进入第二个条件。

    其实,最有趣的是第二个条件 [] == ![] 。

    先看 ![] ,在 JavaScript 中,当用于布尔运算的时候,比如在这里,对象的非空引用被视为 true,空引用 null 则被视为 false。由于这里不是一个 null, 而是一个没有元素的数组,所以 [] 被视为 true, 而 ![] 的结果就是 false 了,如果你在 Visual Studio 的编辑器中输入,就会直接看到提示,表达式永远为假。

    当一个布尔值参与到条件运算的时候,true 会被看作 1, 而 false 会被看作 0,见这里的说明: Javascript 中的相等与不等

    现在条件变成了 [] == 0 的问题了,当一个对象参与条件比较的时候,它会被求值,求值的结果是数组成为一个字符串,[] 的结果就是 '' ,而 '' 会被当作 0 ,所以,条件成立。

    条件内的代码如下:

    f = function () { return false; };
    function g() { return true; }

    注意 f 的前面没有 var ,所以,不是局部变量,因此,这里会通过闭包访问到外部的变量 f, 重新赋值,现在执行 f 函数返回值已经成为 false 了。

    至于 g 则不会有这个问题,这里是一个函数内定义的 g,不会影响到外部的 g 函数。

    最后一行的结果自然也就出来了,就是 false。

    ---------------------------------------------------------------------------------------------------

    今天又同学说到执行的结果不同,我原来是在 Chrome 测试的,现在重新检查一下发现是有问题的。

    Chrome 在执行到签到函数的时候,是先发现 g 函数重新定义了,覆盖了外部的定义,满足条件执行,就是上面的说明。

    在 FireFox 中,直到执行到 if 语句之前,是不会看内部的 g 函数定义的,所以条件根本就不会满足,在执行条件判断之后,才会处理内部的函数定义,但是由于条件没有满足,所以 f 不会被重新定义。返回结果就成为 true.

    在 IE 中,最为特殊,在进入内部函数之后之后,g 既不是外部的定义,也不是内部的定义,而是神奇地成为 undefined 。直接会抛出异常。如果内部没有定义函数 g就可以访问到外部的 g 函数。

  • 相关阅读:
    PAT A1094 The Largest Generation (25 分)——树的bfs遍历
    PAT A1055 The World's Richest (25 分)——排序
    PAT A1052 Linked List Sorting (25 分)——链表,排序
    PAT A1076 Forwards on Weibo (30 分)——图的bfs
    辅导员
    辅导员面试
    C程序设计
    Excel VBA 基本概念
    Excel函数
    导入excel表的数据到数据库ssh
  • 原文地址:https://www.cnblogs.com/haogj/p/3926715.html
Copyright © 2020-2023  润新知