• 《You dont know JS》类型篇总结


    类型

    javaScript中的类型和熟知的一些强类型语言的有关类型的定义是不一样的。在js中,类型的含义是值的内部特征,它定义了值得行为,以使其区别于其他值。(a type is an intrinsic, built-in set of characteristics that uniquely identifies the behavior of a particular value and distinguishes it from other values)

    由此我们就可以看出,js强调的是值的行为,js认为拥有不同行为的值就是不同类型的值,而根据不同行为进行分类,js区分了七种类型:Undefined、Null、Boolean、Number、Object以及ES6新增的Symbol。


    一:null和object

    typeof null === 'object';   //  true
    typeof {} === 'object'; // true
    

    在js中,null被当做object,这是js的一个BUG,修复这个BUG的代价有些大,所以相当时间内不会有什么变化,所以为了准确区分null和object,可以借助取反运算符,如下所示:

    !null === true; // true
    !{} === false;  // true
    
    var a = null;
    if (!a && typeof a === 'object') {  // 为true时,a为null
        ...
    }
    

    如上所示,借助这个区别,我们就可以准确区分null和object了。


    二:typeof function a() {} === 'function'

    如标题所示的结果为true。'function'是object的一个“子类型”。函数是“可调用对象”,它有一个内部属性[[Call]],该属性使其可以被调用。

    typeof [1,2,3] === 'object';    // true
    

    同理,数组也是对象,也是object的一个“子类型”。


    三:JS中的变量没有类型,值有类型

    JS中的变量并不具有类型,所以变量存储的值可以是任意类型且是动态可变的。所以我们说JS是一种“弱类型语言”。

    所以,我们在使用typeof检查类型时,检查的并不是变量的类型,而是该变量存储的值的类型。因为JS中的变量没有类型。注意:typeof运算符的返回值总是一个字符串。


    四:区分undefined和undeclared

    • undefined:未赋值
    • undeclared:未定义

    在js中,undefined表示变量本身已经定义,但是还没有对该变量赋值或者被显示的赋值为undefined。如下所示:

    var a;
    typeof a;   // 'undefined'
    var c = 2;
    typeof c;   // 'number'
    c = a;
    typeof c;   // 'undefined'
    

    与undefined形成鲜明对比的,就是undeclared。如果我们完全还没声明,就直接去调用(注意,这里是直接调用未声明的变量),就会报错,如下所示:

    var a;
    a;  // 'undefined'
    c;  // 'Uncaught ReferenceError: c is not defined'
    

    "c is not defined"并非字面意思表示未定义,这也是为什么要引入一个"undeclared",因为在此处"c is not declared"更准确一些。

    但需要注意的一点是,不论是对于已经定义未赋值的变量,还是对于未定义的变量,typeof操作符都会返回"undefined"。

    var a;
    typeof a;   // undefined
    typeof c;   // undefined
    

    会出现上述这种奇怪的现象,是typeof有一个特殊的安全防范机制。这种安全机制还是比较有用的。我觉得大家都写过如下所示的这种代码,但我们需要使用一个变量时,为了避免一些不必要的操作,可能会先对该变量做一个判断:

    var name = ''
    if (name) { // 如果name的值是空字符串,就不输出
        console.log(name);
    }
    if (age) {  // 如果age的值是小于等于0的值,就不输出
        console.log(age);
    }
    

    现在我们知道,如上所示的代码是存在安全隐患的,我们无法保证name和age都是已经声明过得变量,这就存在安全隐患。这就需要做一个安全验证,这时候typeof的安全机制就有了用处:

    var name = '';
    if (typeof name !== 'undefined' && name) { // 如果name的值是空字符串,就不输出
        console.log(name);
    }
    if (typeof age !== 'undefined' && age) {  // 如果obj.age的值是小于等于0的值,就不输出
        console.log(age);
    }
    

    同时,typeof操作符还可以验证某个变量当前是否有定义,避免同名覆盖。

    if (typeof a === 'undefined') {
        a = {...};
    }
    

    当然,如果是访问对象的一个不存在的属性,是不会像访问未声明的变量那样报错的。

    var obj = {
        name : 'abc'
    }
    if (obj.name) { // obj.name => 'abc'
        console.log(obj.name);  // 'abc'
    }
    if (obj.age) {  // obj.age => 'undefined'
        console.log(obj.age);
    }
    
  • 相关阅读:
    MVC模式的学生信息增删改查
    常用排序算法
    2803 爱丽丝·玛格特罗依德
    3118 高精度练习之除法
    中秋练习题
    poj2011
    P1558 色板游戏
    P1830 轰炸III
    P1656 炸铁路
    1067 机器翻译
  • 原文地址:https://www.cnblogs.com/enjoymylift/p/8351415.html
Copyright © 2020-2023  润新知