JavaScript的数据类型

70 阅读5分钟

一、JavaScript的数据类型

  • JavaScript是一种弱类型(动态)语言,意味着不用提前声明变量的类型,在程序运行过程中,类型会被自动确定;用一个变量可以保存不同类型的数据
    • 数据类型(7种+1种)
      • String:表示0或多个16位Unicode字符序列
      • Number:使用IEEE754格式表示整数和浮点数
      • Boolean:真/假
      • Null:表示一个空对象指针
      • Undefined:一个声明未定义的变量的初始值,没有实际参数的形式参数
      • BigInt:是一种数字类型的数据,它可以表示任意精度格式的整数。
      • Symbol(符号):是原始值,且符号实例时唯一、不可变的。用途是确保对象属性使用唯一标识符,不会发生属性冲突的危险。
      • Object:一种无序名值对的集合
    • typeof操作符可以返回哪些数据类型
      • Undefined "undefined":未定义
      • Boolean "boolean":布尔值
      • Number "number":数值
      • BigInt "bigint":
      • String "string":字符串
      • Symbol "symbol":符号
      • Function "function":函数
      • 其它任何对象,null "object":对象
    • 具体实现
    // 数值
    typeof 37 === 'number';
    typeof 3.14 === 'number';
    typeof(42) === 'number';
    typeof Math.LN2 === 'number';
    typeof Infinity === 'number';
    typeof NaN === 'number'; // 尽管它是 "Not-A-Number" (非数值) 的缩写
    typeof Number(1) === 'number'; // Number 会尝试把参数解析成数值
    typeof 42n === 'bigint';
    // 字符串
    typeof '' === 'string';
    typeof 'bla' === 'string';
    typeof `template literal` === 'string';
    typeof '1' === 'string'; // 注意内容为数字的字符串仍是字符串
    typeof (typeof 1) === 'string'; // typeof 总是返回一个字符串
    typeof String(1) === 'string'; // String 将任意值转换为字符串,比 toString 更安全
    // 布尔值
    typeof true === 'boolean';
    typeof false === 'boolean';
    typeof Boolean(1) === 'boolean'; // Boolean() 会基于参数是真值还是虚值进行转换
    typeof !!(1) === 'boolean'; // 两次调用 ! (逻辑非) 操作符相当于 Boolean()
    // Symbols
    typeof Symbol() === 'symbol';
    typeof Symbol('foo') === 'symbol';
    typeof Symbol.iterator === 'symbol';
    // Undefined
    typeof undefined === 'undefined';
    typeof declaredButUndefinedVariable === 'undefined';
    typeof undeclaredVariable === 'undefined'; 
    // 对象
    typeof {a: 1} === 'object';
    // 使用 Array.isArray 或者 Object.prototype.toString.call
    // 区分数组和普通对象
    typeof [1, 2, 4] === 'object';
    typeof new Date() === 'object';
    typeof /regex/ === 'object'; // 历史结果请参阅正则表达式部分
    // 下面的例子令人迷惑,非常危险,没有用处。避免使用它们。
    typeof new Boolean(true) === 'object';
    typeof new Number(1) === 'object';
    typeof new String('abc') === 'object';
    // 函数
    typeof function() {} === 'function';
    typeof class C {} === 'function'
    typeof Math.sin === 'function';
    // 特殊的
    typeof null === 'object'; // null被认为是一个对空对象的引用
    // 使用new操作符,除Function外的所有构造函数的类型都是'object'
    var str = new String('String');
    var num = new Number(100);
    typeof str; // 返回 'object'
    typeof num; // 返回 'object'
    var func = new Function();
    typeof func; // 返回 'function'
    // 括号有无将决定表达式的类型
    var iData = 99;
    typeof iData + ' Wisen'; // 'number Wisen'
    typeof (iData + ' Wisen'); // 'string'
    
  • 其它:
    • 值的范围:最小(Number.MIN_VALUE==5e-324);最大(Number.MAX_VALUE==1.7976931348623157E+308);Infinity正无穷;-Infinity负无穷;
    • isFinite()函数:判断一个值是不是有限大
    • NaN:“不是数值”,用于表示本来要返回数值的操作失败了
      • NaN==NaN //falseNaN不等于包括NaN在内的任何值
      • isNaN()函数:判断是否“不是数值”。原理是:首先调用对象的valueOf()方法,然后确定返回的值是否可以转换为数值。如果不能再调用toString()方法,并测试其返回值
    • 字符串是不可变的,一旦创建,值就不可再变了。若要修改必须先销毁原始字符串,然后再将另一个新值的保存到该变量。
    • 模板字面量:保留换行字符,可以跨行定义字符串
    let a = 'first \nsecond';
     let b = `first
     second`;
     console.log(a);
     console.log(b);
    
    • 支持字符串插值 ${}
    let value = 5;
    let exponet = 'second';
    let a = value + ' to the ' + exponet + ' power is ' + (value*value);
    let b = `${value} to the ${exponet} power is ${value * value}`;  
    console.log(a); // 5 to the second power is 25
    console.log(b); // 5 to the second power is 25
    

二、列举类型转换有哪些?

  • 强制转换:String(value),Number(value),Boolean(value),parseInt(),parseFloat()[],toString()[适用于数值、布尔值、对象和字符串值;null、undefined不可使用]
    • Boolean():①至少有一个字符的字符串、非0数字、对象===true;②空字符串、数字0、undefined、null、NaN===false
    • Number():转换的是整个值,而不是部分值
    • String():可以把任何值转换成字符串
  • 隐式转换:js默认自动转换,常见场景如下:①if语句自动转换boolean;②运算符:字符串加数字,数字会变成字符串;数字减(乘除大于小于)字符串,字符串会变成数字,如果字符串不是纯数字就会转换成NaN;③类型比较的时候会先转换 == ===;
  • 一些常见的转换
原始值转换目标结果
number布尔值除了0、-0、NaN都为true
string布尔值除了空串都为true
undefined、null布尔值false
引用类型、Symbol布尔值true
number字符串5=>'5'
boolean字符串'true'/'false'
Symbol()字符串'Symbol()'
函数字符串'function func(){}'
数组字符串[1,2]=>'1,2'
对象字符串'[object Object]'
undefined字符串'undefined'
null字符串'null'
string数值空字符串为0, '1'=>1,'a'=>NaN
数组数值空数组为0,存在一个元素且为数字转数字,其他情况NaN
null数值0
undefined数值NaN
除了数组的引用类型数值NaN
symbol数值报错
布尔值数值0/1
{} + {} = "[object Object][object Object]"

三、如何判断数组?

  • 通过检查 constructor 属性来确定某个对象是否为数组(包含单词 "Array"):
function isArray(myArray) {
    return myArray.constructor.toString().indexOf("Array") > -1;
}
// 原型实例化的constructor属性
var a = [];
console.log(a.__proto__.constructor === Array) //f Array(){[native code]}  ;true
console.log(a.constructor === Array)
  • instanceOf方法
    var arr = [];
    console.log(arr instanceof Array);
    
    • 扩展:实现原理(判断左边对象的原型链上是否存在右边的原型)
  • Array.isArray()
    var ar = [];
    Array.isArray(arr);
    
  • toString()
    if(!Array.isArray()){
    Array.isArray = function(arg){
        return Object.prototype.toString.call(arg)==='[object Array]';
    }
    }
    var array = [];
    Array.isArray(array);
    

Ps:参考文档

  1. JavaScript进阶系列-类型转换、隐式类型转换
  2. JavaScript 数据类型和数据结构
  3. JavaScript高级程序设计(第四版)
  4. 判断数组的方式