• JavaScript 的类型和值


    JavaScript 的类型和值

    1. 类型

    1.1 七种内置类型

    • 空值(null)
    • 未定义(undefined)
    • 布尔值(boolean)
    • 字符串(string)
    • 数字(number)
    • 对象(object)
    • 符号(symbol)

    符号(symbol)常作唯一标识,属于es6(ECMAScript2015)新增内容

    对象类型 object之外其他的都是基本类型

    1.2 typeof 运算符

    注意:上述’七种类型’使用类型检测运算符typeof 得到的结果却不一定是他们本身~

    观察以下代码:

    typeof undefined === 'undefined' // true 
    typeof 123 === 'number' // true
    typeof '123' === 'string' // true
    ...
    typeof null === 'null' // false
    typeof null === 'object' // true 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    正常来讲 typeof 可以正确获取类型。但是 null 无法获取到 null,而是 'object'。这是 JavaScript 的一个 bug,可能以后也不会修复了…

    1.3 值和类型

    你们会发现,JavaScript 中的变量是没有类型的,不能使用 String str = ‘123’ 来定义一个变量。在 js 中,只有值存在类型,对于一个变量,可以拥有任何类型。所以上述的 typeof 测试的并不是变量是什么类型,而是测试变量所拥有的值

    1.3.1 undefined 和 undeclared

    变量在无值时为 undefined,变量不存在时(在作用域未声明)为 undeclared

    观察以下代码:

    var hhh = 'a'
    var xixixi 
    
    typeof hhh === 'string' // true
    hhh // 'a'
    
    typeof xixixi = 'undefined' // true
    xixixi // undefined
    
    typeof hahaha === 'undefined' // true
    hahaha //  ReferenceError: hahaha is  not defined
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    注意:undeclared 在浏览器里输出为 ReferenceError: xx is not defined,容易误解为 undefined,实际上应该输出为 xx is not found 或者 xx is not declared,同时 typeof 处理 undeclared 是输出 ‘undefined’ 的,这是不合理的,期待输出’undeclared’。

    2. 值

    2.1 数组

    和其他强类型语言不同,在 JavaScript 中,数组可以容纳任何类型的值,可以是字符串、数字、对象(object),甚至是其他数组(多维数组就是通过这种方式来实现的)

    var a = [ 1, "2", [3] ];
    a.length; // 3
    a[0] === 1; // true
    a[2][0] === 3; // true
    
    • 1
    • 2
    • 3
    • 4

    给数组设定值的时候无需预先设置大小,可以使用字面量的形式申明一个数组

    var arr = []
    arr[0] = 0
    arr[2] = 2
    arr[1] // undefined
    arr.length = 3 // 虽然 arr[1] 为定义,但是数组长度 = 最大索引 - 1 
    
    • 1
    • 2
    • 3
    • 4
    • 5

    a[1] 的值为 undefined,但这与将其显式赋值为 undefined(a[1] = undefined)还是有所区别

    使用 delete 运算符可以将元素从数组中删除,但是删除后,数组的 length 属性并不会发生变化。

    如果字符串键值能够被强制类型转换为十进制数字的话,它就会被当作数字索引来处理。

    在数组中加入 字符串键值 / 属性 并不是非常推荐。

    var a = [ ];
    
    a["13"] = 42;
    
    a.length; // 14
    
    • 1
    • 2
    • 3
    • 4
    • 5

    类数组

    类数组对象:是指在 JavaScript 中有一些对象可能并不是真正的数组,但它们可以表现得跟数组一样。比如说 arguments 对象或者 jQuery 选择元素集合等。它们可以通过 index 来访问元素,并且有 length 属性,但是缺少数组所拥有的其他方法,例如 push, pop,slice 等。

    常见的类数组对象有:

    • JavaScript的arguments对象
    • DOM方法的返回结果,如 document.getElementsByTagName 或 document.childNodes
    • 字符串

    类数组到数组的转换方法有:

    1. Array.prototype.slice.call()

      使用Array.prototype.slice.call()方法能将具有length属性的对象转成数组。

    var arrayLike = {0: 'name', 1: 'age', 2: 'sex', length: 3 }
    var arr = Array.prototype.slice.call(arrayLike); // ['name', 'age', 'sex']
    
    • 1
    • 2
    1. Array.from()
      Array.from() 方法从一个类似数组或可迭代对象中创建一个新的,浅拷贝的数组实例。
    let arrayLike = {0: 'name', 1: 'age', 2: 'sex', length: 3 };
    let arr = Array.from(arrayLike); // ["name", "age", "sex"]
    
    • 1
    • 2
    1. 扩展运算符 “…”
      扩展运算符可以将某些数据结构转为用逗号分隔的参数序列。
    let arrayLike = {0: 'name', 1: 'age', 2: 'sex', length: 3 }
    let arr = [...arrayLike];  // ["name", "age", "sex"]
    
    • 1
    • 2

    如果类数组没有 length 属性或者成员不是按照顺序排序的,上述方法可能不能很好的进行转换。在这种情况下,可能需要借助其他方法,例如添加元素到空数组中。

    var array = Array.prototype.concat.apply([], arguments);
    
    • 1

    2.2 字符串

    字符串和数组其实是有的类似的。

    var a = "foo";
    var b = ["f","o","o"];
    
    • 1
    • 2

    它们都是类数组,都有 length 属性以及 indexOf(…)(从 ES5开始数组支持此方法)和 concat(…) 方法

    JavaScript 中字符串是不可变的,而数组是可变的。并且 a[1] 在 JavaScript 中并非总是合法语法,在老版本的 IE 中就不被允许(现在可以了)。正确的方法应该是 a.charAt(1)

    字符串不可变是指字符串的成员函数不会改变其原始值,而是创建并返回一个新的字符串。而数组的成员函数都是在其原始值上进行操作。

    示例:

    字符串无法使用 Array.prototype.reverse()(因为它是不可变更的)

    解决方案:

    var str = '123'
    var newStr = str
     // 将a的值转换为字符数组
     .split( "" )
     // 将数组中的字符进行倒转
     .reverse()
     // 将数组中的字符拼接回字符串
     .join( "" );
    newStr; // '321'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2.3 数字

    JavaScript 只有一种数值类型:number(数字),包括“整数”和带小数的十进制数。此处“整数”之所以加引号是因为和其他语言不同,JavaScript 没有真正意义上的整数,这也是js的‘特性’。

    2.3.1 语法

    • JavaScript 中的数字常量一般用十进制表示
    • 数字前面的 0 可以省略
    • 小数点后小数部分最后面的 0 也可以省略
    • 特别大和特别小的数字默认用指数格式显示,与 toExponential() 函数的输出结果相同。
    var a = 5E10;
    a; // 50000000000
    
    a.toExponential(); // "5e+10"
    
    var b = a * a;
    b; // 2.5e+21
    
    var c = 1 / a;
    c; // 2e-11
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • tofixed(..) 方法可指定小数部分的显示位数
    var a = 42.59;
    a.toFixed( 0 ); // "43"
    a.toFixed( 1 ); // "42.6"
    a.toFixed( 2 ); // "42.59"
    a.toFixed( 3 ); // "42.590"
    a.toFixed( 4 ); // "42.5900"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • toPrecision(..) 方法用来指定有效数位的显示位数
    var a = 42.59;
    a.toPrecision( 1 ); // "4e+1"
    a.toPrecision( 2 ); // "43"
    a.toPrecision( 3 ); // "42.6"
    a.toPrecision( 4 ); // "42.59"
    a.toPrecision( 5 ); // "42.590"
    a.toPrecision( 6 ); // "42.5900"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • .运算法是有效的数字字符,会被优先识别为数字常量的一部分,然后才是对象的属性访问运算符
    42.toFixed( 3 ); // SyntaxError
    
    (42).toFixed( 3 ); // "42.000"
    0.42.toFixed( 3 ); // "0.420"
    42..toFixed( 3 ); // "42.000"
    42 .toFixed(3); // "42.000" 不建议使用
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 数字常量还可以用其他格式来表示,如二进制、八进制和十六进制
    0xf3; // 243的十六进制
    0Xf3; // 同上
    0363; // 243的八进制
    // es6 支持以下的格式
    0o363; // 243的八进制
    0O363; // 同上
    0b11110011; // 243的二进制
    0B11110011; // 同
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2.3.2 数值边缘与机器精度(machine epsilon)

    看以下代码:

    它们相加的结果并非刚好等于0.3,而是一个比较接近的数字 0.30000000000000004,所以条件判断结果为 false

    0.1 + 0.2 === 0.3; // false
    
    • 1

    以上结果是 JavaScript 无法完全精确呈现数字导致的~

    那么怎么判断 0.1 + 0.2 和 0.3 是否相等呢?

    最常见的方法是设置一个误差范围值,通常称为“机器精度”(machine epsilon),对JavaScript 的数字来说,这个值通常是 2^-52 (2.220446049250313e-16)

    从 ES6 开始,该值定义在 Number.EPSILON 中,我们可以直接拿来用,也可以为 ES6 之前的版本写 polyfill:

    if (!Number.EPSILON) {
     Number.EPSILON = Math.pow(2,-52);
    }
    
    • 1
    • 2
    • 3

    可以使用 Number.EPSILON 来比较两个数字是否相等(在指定的误差范围内):

    function numbersCloseEnoughToEqual(n1,n2) {
     return Math.abs( n1 - n2 ) < Number.EPSILON; // Math.abs 取绝对值
    }
    var a = 0.1 + 0.2;
    var b = 0.3;
    numbersCloseEnoughToEqual( a, b ); // true
    numbersCloseEnoughToEqual( 0.0000001, 0.0000002 ); // false
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2.3.3 检测整数

    if (!Number.isInteger) {
     Number.isInteger = function(num) {
     return typeof num == "number" && num % 1 == 0;
     };
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    realloc一定要注意的细节,不然很容易崩溃
    智慧医疗新篇章:山海鲸可视化引领行业变革
    PyTorch实现注意力机制及使用方法汇总,附30篇attention论文
    cmake 中经常出现的 关键词 scope 中的 三种:PUBLIC PRIVATE INTERFACE
    【软件测试】一位优秀测试工程师具备哪些知识和经验?
    医学影像归档与通讯系统(PACS)系统源码 PACS三维图像后处理技术
    假设检验3
    Docker入门学习笔记
    torch模块常用方法总结
    win安装vue并运行 vue-admin-template
  • 原文地址:https://blog.csdn.net/m0_66492535/article/details/133926776