那些年我们一起踩过的坑_ZeroRockie的博客-程序员宝宝

技术标签: web  前端  javascript  

极限挑战 43道 JS 题目,你对了多少道!

​ 今天笔者整理了自己曾经踩过的坑,当然,有些坑不掉个几次是记不牢的,有点惨emmm,这些题型涉及的知识面非常广,涵盖了 JS 原型,函数细节,强制转换,闭包扥知识点.而且都是一些非常细节的东西,透过这些细节可以折射出很多高级的 JS 知识点,你可以先思考一下结果,然后在看我的解析,为了解释这些细节知识点,笔者翻了很多书和资料,弥补了很多 JS 知识盲点.

​ 勇士,请开始你的冒险之旅,请认真对待每一道题! 考试时间 120 分钟(非上机考试) Let’s Go!!

  1. parentInt 遇上 map

    ["1","5","2",2].map(parseInt);
    // A [1, 5, 2, 2]
    // B ["1", "5", "2", 2]
    // C [1, NaN, 2, 2]
    // D [1, NaN, NaN, 2]
    

Answer is D.

正确的结果是 [1, NaN, NaN, 2],因为 parseInt 函数接收两个参数,语法parseInt(string, radix),在数组的 map 方法中的回调函数接收3个参数 CallBack(currentValue,currentIndex,array) ;MDN文档中明确指明 parseInt的第二个参数radix为一个介于2到36之间的整数,表示上述字符串的基数。比如参数"10"表示使用我们通常使用的十进制数值系统。始终指定此参数可以消除阅读该代码时的困惑并且保证转换结果可预测。当未指定基数时,不同的实现会产生不同的结果,通常将值默认为10

参考资料:

MDN : parseInt

MDN : Array.prototype.map

  1. 神奇的 null

    [typeof null,null instanceof Object]
    //A ["object",false]
    //B [null, false]
    //C ["object",true]
    //D other
    

    Answer is A.

    很多人可能对于typeof null为 “object” 的结果可能觉得很正常,因为 null就是一个特殊的对象,都是既然是一个对象,为什么 null instanceof Object结果为 false 呢? 其实,typeof null结果为 “object” 这一结果是JavaScript 这门语言的一个 Bug,笔者在**《JavaScript高级程序》**一书中了解过,原理是这样的,不同的对象底层都是二进制,在 JavaScript 中二进制前3位都为 0 的话,会被判断其类型为 “object”,null的二进制全是 0,自然前三位也是 0,所以 typeof null 的结果才是 “object”,而instance运算符是用于测试构造函数的prototype属性是否出现在对象的原型链中的任何位置,object instanceof constructor

    参考资料:

    MDN: instanceof

    MDN: null

  2. 怒气冲天的 reduce

    console.log([3,3,2].reduce(Math.pow))
    console.log([].reduce(Math.pow))
    //A 8, undefined
    //B 81, 0
    //C 81, NaN
    //D 81, TypeError
    

    Answer is D

    数组的reduce语法为: arr.reduce(callback[, initialValue]),回调函数callback接收4个参数,分别为

    accumulator 累计器累计回调的返回值; 它是上一次调用回调时返回的累积值

    currentValue 数组中正在处理的元素

    currentIndex 数组中正在处理的当前元素的索引(可选)。 如果提供了initialValue,则起始索引号为0,否则为1

    array 当前数组

    除了接受回调函数外,还可以接受一个初始值 initialValue => 作为第一次调用 callback函数时的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用 reduce 将报错。

    函数返回值为函数累计处理的结果

    [3,3,2].reduce(Math.pow)没有设置初始值initialVaule,所以从数组的第0项开始计算,

    第一步: Math.pow(3,3,1,[3,3,2]) 结果是 9,累计结果 9

    第二步: Math.pow(9,2,2,[3,3,2]) 结果是 81,累计结果 81

    [].reduce(Math.pow) 抛出错误,原因,数组为空且没有设置初始值!

    MDN: Array.prototype.reduce

  3. 调皮的优先级

    var status = true;
    console.log("我说:" + status ? "你个糟老头" : "你大爷还是你大爷")
    //A "我说:你个糟老头"
    //B "我说:你大爷还是你大爷"
    //C "你个糟老头"
    //D NaN
    

Answer is C

这里考查的是算术运算符优先级,因为 +的优先级高于? :三元运算符,所以 “我说true” ? “你个糟老头” : “你大爷还是你大爷”,非空字符串在 JS 中的布尔值表示真,所以最终结果为 “你个糟老头”

MDN: 算术运算符优先级

  1. 神出鬼没的变量提升

    var myBehavior = "我要好好学习"
    !function (){
        if(typeof myBehavior == "undefined"){
            var myBehavior = "不,我不想";
        }
        console.log(myBehavior);
    }()
    //A "我要好好学习"
    //B "不,我不想"
    //C undefined
    //D other
    

Answer is B

在 JavaScript 中,函数和变量都存在变量提升的机制

匿名函数在调用时没有输出 “我要好好学习” 而是 “不,我不想”,这是因为 JS 内部存在一个过程分析。

当函数运行的一瞬间主要分析3各方面。

  1. 参数;

  2. 局部变量声明;

  3. 函数声明;

此时引入激活对象(Active Object) 简称 AO

在函数运行的一瞬间,先形成一个激活对象叫ACTIVE OBJEECT ,简称AO.

AO的对象是用来储存一个函数的相关参数,局部变量等。

函数内部无论是引用参数,还是引用局部变量,都到AO上找

AO流程可以这样理解,Show Code =>

var myBehavior = "我要好好学习"
!function (){
     
    var myBehavior;//变量提升
    if(typeof myBehavior == "undefined"){
     
        myBehavior = "不,我不想";
    }
    console.log(myBehavior);
}()

MDN: 变量提升

  1. 独特的过滤器

    var arr = [1,2,3];
    	arr[7] = undefined;
    var a = arr.filter(function(item){
        return typeof item == "undefined";
    })
    console.log(a)
    //A [undefined*5]
    //B []
    //C [undefined]
    //D undefined
    

    Answer is C

    filter 为数组中的每个元素调用一次 callback 函数,并利用所有使得 callback 返回 true 或等价于 true 的值的元素创建一个新数组。callback 只会在已经赋值的索引上被调用,对于那些已经被删除或者从未被赋值的索引不会被调用。那些没有通过 callback 测试的元素会被跳过,不会被包含在新数组中。

    MDN: Array.prototype.filter

  2. 字符串陷阱

    var str = new String("A");
    switch(str){
        case "A": 
        	console.log("str is A");
        	break;
        case undefined: 
        	console.log("str is undefined");
        	break;
         case null: 
        	console.log("str is null");
        	break;
        default: 
        	console.log("other");
        	break;
    }
    //A "str is A"
    //B "other"
    //C "str is undefined"
    //D "str is null"
    

Answer is B

switch中的比较是===严格等于的, new String(“A”) 返回的是一个对象,而 String(“A”) 返回的是字符串 “A”.

以下内容采摘至 MDN

基本字符串和字符串对象的区别

请注意区分 JavaScript 字符串对象和基本字符串值 . ( 对于 BooleanNumbers 也同样如此.)

字符串字面量 (通过单引号或双引号定义) 和 直接调用 String 方法(没有通过 new 生成字符串对象实例)的字符串都是基本字符串。JavaScript会自动将基本字符串转换为字符串对象,只有将基本字符串转化为字符串对象之后才可以使用字符串对象的方法。当基本字符串需要调用一个字符串对象才有的方法或者查询值的时候(基本字符串是没有这些方法的),JavaScript 会自动将基本字符串转化为字符串对象并且调用相应的方法或者执行查询。

MDN: String

  1. 连续跳坑的字符串

    var str = String("A");
    switch(str){
        case "A": 
        	console.log("str is A");
        	break;
        case undefined: 
        	console.log("str is undefined");
        	break;
         case null: 
        	console.log("str is null");
        	break;
        default: 
        	console.log("other");
        	break;
    }
    //A "str is A"
    //B "other"
    //C "str is undefined"
    //D "str is null"
    

    Answer is A

    结果解析请看上一题!

  2. 意外的非奇即偶

    //判断奇数
    function isOdd(num){
        return num % 2 == 1;
    }
    //判断偶数
    function isEven(num){
        return num % 2 == 0;
    }
    function isSane(num){
        return isOdd(num) || isEven(num);
    }
    var a = [0,3,2,-9,Infinity];
    //A [true,true,true,true,true]
    //B [true,true,true,true,false]
    //C [true,true,true,false,true]
    //D [true,true,true,false,false]
    

    Answer is D

    在判断数字的情况下,判断奇偶数有的时候不是 % 2 看其结果是否为 1 or 0 决定的,例如如果判断奇数的话, -9 % 2 = -1,-9 虽然是奇数,但是它的模却不是 1,还有 Infinite 代表无穷大,Infinity % 2 = NaN

  3. 无耻的 parseInt 老贼

    parseInt(4,4);
    parseInt(6,37);
    parseInt(010);
    parseInt("010");
    //A 1, 6 10, 10
    //B NaN, 6, 8,10
    //C NaN, 6, 8, 8
    //D other
    

    Answer is D

    上述代码其运行结果为: NaN,NaN,8,10

    parseInt的第二个参数 radix表示基数,范围 2 - 36;

    第一题已有更加详细的解析,如需了解,请自行上拉

  4. 鲜为人知的数组原型

    Array.isArray(Array.prototype);
    //A true
    //B null
    //C false
    //D undefined
    

    Answer is A

    其实数组的原型就是数组,这个知识点个人觉得应该是鲜为人知的,MDN文档说明过

    MDN: Array.prototype

  5. 令人恐惧的强制转换

    var a = [0];
    if ([0]) {
      console.log(a == true);
    } else {
      console.log("wut");
    }
    
    // A. true
    // B. false
    // C. "wut"
    // D. other
    

    Answer is B

    规范指出,== 过程中,如果有一个操作值是布尔值,那么会先把他转化为数字,然后进行 [0] == 1的比较,同时规范指出如果其他类型和数字进行比较,会尝试把这个类型转换为数字在进行宽松比较,而对象(数组也是对象)会调用它的toString()方法,将[0] 转成 “0”,“0” == 1的比较中,字符串 “0” 会转成数字 0,所以 0 == 1结果为false.

    以上资料是笔者在《你不知道的javascript》(中卷)了解的

    强制类型转化个人觉得不是一两句话就可以解释的通,还是得饱读经书才可轻易应付.有兴趣的还可以去 GitHub,查看关于这方面的免费书籍,点击即可跳转 You-Dont-Know-JS

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_40181779/article/details/89369030

智能推荐

DATAWINDOW技巧2_web_ser的博客-程序员宝宝

 66、数据窗口dw_1中有一列是用下拉数据窗口表示,怎么才能动态改变下拉数据窗口,也就是动态调用不同的下拉数据窗口datawindowchild ldwc_1 getchild("含有dddw的字段名", ldwc_1) ldwc_1.dataobject = "d_1" //这里动态改变d_2, d_3 ldwc_1.settransobject(sqlca) ldwc_1.retri

数据结构-AVL树_hola_f的博客-程序员宝宝

AVL树:带有平衡条件的二叉查找树,要求每个节点的左子树和右子树的高度最多差1。通常,AVL树通过旋转操作保持平衡条件。不平衡的可能情况:节点a的左儿子左子树进行插入节点a的右儿子右子树进行插入节点a的左儿子右子树进行插入节点a的右儿子左子树进行插入其中情况1、2都是通过单旋转就可以解决了,而情况3、4需要通过双旋转来解决。AVL树的声明:struct avlNode;

高精度计时-利用intel CPU一个机器指令_ldpxxx的博客-程序员宝宝

本文的出处:http://down.dns.sh.cn/article/236/417/2008/2008090187669.asp对关注性能的程序开发人员而言,一个好的计时部件既是益友,也是良师。计时器既可以作为程序组件帮助程序员精确的控制程序进程,又是一件有力的调试武器,在有经验的程序员手里可以尽快的确定程序的性能瓶颈,或者对不同的算法作出有说服力的性能比较。在Windows平台下,常

算法与数据结构详解_万wu皆可爱的博客-程序员宝宝

一、 什么是算法和数据结构你可能会在一些教材上看到这句话:程序 = 算法 + 数据结构算法算法(Algorithm):是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制。也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出。(任何代码片段都可视为算法)数据结构数据结构(Data Structures):是计算机存储和组织数据的一种方式,可以用来高效地处理数据。什么样的程序才是好的程序?好的程序设计无外乎两点,“快"和"省”。"快"指

代码静态检测——QAC_注释远方的博客-程序员宝宝

一、前言二、QAC构建三、QAC常见报警3.1 Msg(2:4700) metric value out of threshold range: STCYC=22:STLIN=307:STMCC = 48;函数内执行的代码行数少于5,比如一个函数中只有if-else if...或者switch-case3.2 Msg(2:4304) An expression of 'essentially Boolean type'is being cast to unsigne...

html5css3网站设计基础教程答案,HTML5+CSS3网站设计基础教程_动手实践源代码_李子骅 luin的博客-程序员宝宝

【实例简介】HTML5+CSS3网站设计基础教程_动手实践源代码 chapter01 到 chapter10【实例截图】【核心代码】HTML5CSS3网站设计基础教程_动手实践源代码└── HTML5+CSS3网站设计基础教程_动手实践源代码├── chapter01│ ├── images│ │ └── designer.jpg│ └── index.html├── chapte...

随便推点

python可视化stackplot函数用法-绘制堆积面积图。_海宝7号的博客-程序员宝宝

matplotlib.pyplot.stackplot(x, *args, labels=(), colors=None, baseline=’zero’, data=None, **kwargs)堆栈图的思想是随着时间的推移显示“部分到整体”。它用于表示各种数据集而不会彼此重叠。Stackplot用于绘制堆积面积图。它显示完整的数据以进行可视化。它显示了每个零件相互堆叠以及每个零件如何构成完整的图形。它显示数据的各种组成部分,其行为类似于饼图。它具有x-label,y-label和标题,其中各个部分可

初学数据仓库项目理解_nafrul的博客-程序员宝宝

Teradata数据仓库基础层和中间层      来Teradata实习2个月了,今天我分享一下之前在学习中的困惑,内容都很基础,但对刚来实习的同道们理清思路,应该会有所帮助吧,文中如有错误,请指正。      本文主要讲事实表和维度表从源系统到中间层的初始加载和增量加载的过程,列举了一张事实表和一张维度表,里面的代码为ETL开发的源代码。对其中的一些概念,做了自己的理解。

Java socket经典示例_齊帥的博客-程序员宝宝

事实上网络编程简单的理解就是两台计算机相互通讯数据而已.对于程序员而言,去掌握一种编程接口并使用一种编程模型相对就会显得简单的多了.Java SDK提供一些相对简单的Api来完成这些工作.Socket就是其中之一.对于Java而言.这些Api存在与java.net 这个包里面.因此只要导入这个包就可以准备网络编程了.     网络编程的基本模型就是客户机到服务器模型.简单的说就是两个进程之间相

【Python】安装.whl类库报错“XXX is not a supported wheel on this platform”的解决方案_duanlianvip的博客-程序员宝宝

问题今天在部署系统时,需要安装类库“MarkupSafe-1.1.1-cp37-cp37m-macosx_10_6_intel.whl”,在CentOS7.6系统执行安装命令“pip3 install MarkupSafe-1.1.1-cp37-cp37m-macosx_10_6_intel.whl”,提示错误。解决经查阅资料,修改包名“MarkupSafe-1.1.1-cp37-cp37m-macosx_10_6_intel.whl”至“MarkupSafe-1.1.1-cp37-none

图的遍历:DFS和BFS_请对这个图分别进行dfs和bfs_strawberry zong的博客-程序员宝宝

DFSDFS即深度搜索,每次都沿着路径到不能再前进的时候才退回到最近的岔口。具体不再详细论述。两个小概念:(1)连通分量: 在无向图中,如果有两个顶点可以相互到达(可以是通过一定的路径间接到达)那么就称这两个顶点连通。如果图中任意两个点都连通,则称图G为连通图;否则称它为非连通图,且称其中的极大连通子图为连通分量。(2)强连通分量:在有向图中,如果两个顶点可以各自通过一条有向路径到达...

Activiti工作流之流程变量_空城1995的博客-程序员宝宝

1.什么是流程变量流程变量在 activiti 中是一个非常重要的角色,流程运转有时需要靠流程变量,业务系统和 activiti 结合时少不了流程变量,流程变量就是 activiti 在管理工作流时根据管理需要而设置的变量。比如在请假流程流转时如果请假天数大于 3 天则由总经理审核,否则由人事直接审核,请假天数就可以设置为流程变量,在流程流转时使用。注意:如果将 pojo 存储到流...

推荐文章

热门文章

相关标签