JavaScript经典面试题(1) -- 关于typeof的陷阱

   使用 typeof bar === "object" 来确定 bar 是否是对象的潜在陷阱是什么?如何避免这个陷阱?
   潜在陷阱是:当 bar 为 null 时,也会被认为是对象。
   如何避免:方法如下
   1、我们发现当bar为null时,typeof bar === "object"的结果也是true,可见这种单一判断不再可取。

    /*null*/
    var bar = null;
    console.log(typeof bar === "object");//true
    console.log((bar !== null) && (typeof bar === "object"));//fasle

当我们加上 "bar !== null" 这一限制条件后,得到了想要的结果。可还有几种其他情况也需要注意。
2、判断函数

    /*函数*/
    var bar1 = function(){
        // do something
    }
    console.log(typeof bar1 === "object");//fasle
    console.log((bar1 !== null) && (typeof bar1 === "object"));//fasle
    console.log((bar1 !== null) && ((typeof bar1 === "object")||(typeof bar1 === "function")));//true

3、判断数组

    /*数组*/
    var bar2 = [];
    console.log(typeof bar2 === "object");//true
    console.log((bar2 !== null) && (typeof bar2 === "object"));//true
    console.log((bar2 !== null) && (typeof bar2 === "object") && (toString.call(bar2)  !== "[object Array]"));//fasle

4、另附Object.prototype.toString.call()方法的使用,以便和 "typeof"方法做对比区分。

    /* ps:toString.call()方法 */
    console.log(Object.prototype.toString.call(null));      // "[object Null]"  
    console.log(Object.prototype.toString.call(undefined)); // "[object Undefined]"
    console.log(Object.prototype.toString.call("abc"));     // "[object String]"
    console.log(Object.prototype.toString.call(123));       // "[object Number]"
    console.log(Object.prototype.toString.call(true));      // "[object Boolean]"

    /* 函数类型 */
    function fn(){
        console.log("test");
    }
    console.log(Object.prototype.toString.call(fn)); // "[object Function]"

    /* 日期类型 */
    var date = new Date();
    console.log(Object.prototype.toString.call(date)); // "[object Date]"

    /* 数组类型 */
    var arr = [1,2,3];
    console.log(Object.prototype.toString.call(arr)); // "[object Array]"

基础最重要,好多陷阱都是在大家不太注意的小点上。我本着从头开始,狠抓细节的学习态度,想要从一点一滴里去注意有可能是日后潜在的大bug。
以上。
   2018 08 03 补充内容:关于变量连续声明中的变量类型判断

(function(){
    var a = b = 3;
})();
console.log(typeof a == 'undefined'); // true
console.log(typeof b == 'undefined'); // fasle

如上所示,在匿名函数中,连续声明变量b和a,然后控制台输出其变量类型的判断结果,发现a确实是局部变量,所以是 undefined,结果为true;但b却不是,说明b是全局变量。

notes:

var a = b = 3 不等同于 var b = 3; var a = b;

而是等同于 b = 3; var a = b;

所以此时的变量b声明是不加关键字var的,也就是说变量b是全局变量。

ps: 如果使用严格模式 "use strict";,则控制台不会有输出,直接报错 "b is not defined"。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 4,255评论 0 13
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,837评论 18 399
  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 29,758评论 8 265
  • 零基础学水彩,希望能够通过不断的练习来取得进步。 这幅图芦苇部分的线条画得太乱了…毛笔的使用技巧还没有完全掌握。 ...
    红贝雷阅读 755评论 4 6
  • 之前试着自己使用requireJS进行模块化组件,但是这样做的网络请求量很大(这里是指生成的 数量过多),有没有...
    春木橙云阅读 235评论 0 1