有一道 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 函数。

一道 JavaScript 面试题的更多相关文章

  1. 学生问的一道javascript面试题[来自腾讯]

    function Parent() { this.a = 1; this.b = [1, 2, this.a]; this.c = { demo: 5 }; this.show = function ...

  2. 一道Javascript面试题引发的血案

    文章首发于szhshp的第三边境研究所,转载请注明 先来看几道面试题,公司的开发们都尝试做了一下,然而基本没有人能够全部答对. 覆盖的考点很多,也有一些难度,题目挺有意思建议手动执行一边玩玩. Que ...

  3. 一道javascript面试题

    下面表达式比较的结果分别是什么? 1. []=="0" 2. []==0 3. "0"==0 4. []==false 5. []==[] 大家可以试试写下自己 ...

  4. 腾讯的一道JavaScript面试题

    //题目:分别弹出什么内容? <!-- function test(){ this.a = 1; alert(this); //[object Window] } test(); var t = ...

  5. 一道javascript面试题(闭包与函数柯里化)

    要求写一个函数add(),分别实现能如下效果: (1)console.log(add(1)(2)(3)(4)()); (2)console.log(add(1,2)(3,4)()); (3)conso ...

  6. 你应该知道的25道Javascript面试题

    题目来自 25 Essential JavaScript Interview Questions.闲来无事,正好切一下. 一 What is a potential pitfall with usin ...

  7. 10道典型的JavaScript面试题

    问题1: 作用域(Scope) 考虑以下代码: (function() { ; })(); console.log(b); 上述代码会打印出5.这个问题的陷阱就是,在立即执行函数表达式(IIFE)中, ...

  8. new与属性访问的顺序,从一道JS面试题说起

    这段时间一直在研究设计模式,在看工厂模式的时候,看到一段代码 VehicleFactory.prototype.createVehicle = function ( options ) { if( o ...

  9. 174道 JavaScript 面试题,助你查漏补缺

    最近在整理 JavaScript 的时候发现遇到了很多面试中常见的面试题,本部分主要是作者在 Github 等各大论坛收录的 JavaScript 相关知识和一些相关面试题时所做的笔记,分享这份总结给 ...

随机推荐

  1. android 为应用程序创建桌面快捷方式技巧分享

    手机装的软件过多,找起来很不方便,所以在主页面有一个快捷方式的话会很不错的,本文将介绍如何实现,需要了解跟多的朋友可以参考下     我们开发一款软件后,如果手机装的软件过多,去翻的话会很难翻的,所以 ...

  2. C/C++ 函数压栈方式

    一,不同关键字,系统压栈方式 1,如果函数func是__cdecl(VC下的默认调用方式),调用时情况如下 int   main()   {   //参数从右到左压栈   push   4   pus ...

  3. discuz!3 二次开发C#学者

    PHP入门,从搞数据库开始: 大致看了以下PHP还是很简单的 比如链接数据库,就这么几行,比asp.net简单的多,就是需要自己搞数据的显示,需要精通HTML和代码生成技术: <?php $co ...

  4. MyEclipse背景色不伤眼+字体大小调节+代码格式化不换行

  5. Win7+VMware Workstation环境下的CentOS-Linux网络连接设置

    Win7+VMware Workstation环境下的CentOS-Linux网络连接设置 http://blog.sciencenet.cn/blog-430991-507041.html   近日 ...

  6. ci模板布局方式

    1.修改Loader链式加载header和footer方式 参考:http://stackoverflow.com/questions/9540576/header-and-footer-in-cod ...

  7. ylbtech-LanguageSamples-Struct(结构)

    ylbtech-Microsoft-CSharpSamples:ylbtech-LanguageSamples-Struct(结构) 1.A,示例(Sample) 返回顶部 “结构”示例 本示例演示结 ...

  8. web.xml配置

    <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" ...

  9. c#程序中使用"like“查询access数据库语句的问题

    在写使用access数据库的c#程序过程中,遇到各种莫名奇妙的问题.例如使用"like"进行模糊查询,在access查询视图中要使用"*"做模糊匹配(sql中是 ...

  10. 用java程序调用ffmpeg执行视频文件格式转换flv

    用java小例题说明更直观:(可以直接编译运行)环境我在windows平台下测试的...需要在e:/下有ffmpeg.exe;mencoder.exe;drv43260.dll;pncrt.dll共4 ...