JS的基本数据类型

257 阅读15分钟

    ECMAScript的数据类型分为基本和复杂两类。基本数据类型有:Number、String、Boolean、Undefined、Null、Symbol这6种,复杂类型是Object。本文主要讨论的是基本数据类型。

一、Number

 javascript只有一种数字类型,它在内部被表示为64位的浮点数,和java的double数字类型一样,与其它大多数编程语言不同的是,它没有分离出整数类型和浮点型。javascript中的所有数字都用浮点数值表示。数字Number是javascript中基本的原始数据类型,同时javascript也支持Number对象。它是一个原始数值的包装对象,在需要的时候,javascript会自动在原始形式和对象形式之间进行转换。

    当一个数字直接出现在javascript程序中,称之为数字的字面量,而当Number()使用new操作符用作构造函数时,称之为Number对象。

  1. 1、整数直接量 

    javascript的整数表示共有四种字面量格式是十进制、二进制、八进制、十六进制。但在进行算术计算时,所有以二进制、八进制和十六进制表示的数值最终都将被转换成十进制数值。

    a: 八进制字面值的第一位必须是0,然后是八进制数字序列(0-7)。如果字面值中的数值超出了范围,那么前导0将被忽略,后面的数值被当作十进制数解析。(严格模式下是禁止的,所以最好不用)。

    b. 十六进制字面值的前两位必须是0x,后跟十六进制数字序列(0-9,a-f),字母可大写可小写。如果十六进制中字面值中的数值超出范围会报错。

    c. 二进制字面值的前两位必须是0b,如果出现除0、1以外的数字会报错。

  1. 2、浮点型直接量

    浮点数是指数值中必须包含一个小数点,且小数点后面必须至少有一位数字。与整数支持多进制不同,一般地,浮点数只可用十进制表示。

    虽然小数点前面可以有整数,但是不推荐。涉及到浮点数的比较和运算一定要小心。

  1. 3、特殊数值

    Number.MAX_VALUE          最大值

    Number.MIN_VALUE           最小值

    (+-)Infinity                  正负无穷大

    NaN(not a number)             非数字

    正负0                      js内部存在2个0它们等价

 console.log(Number.MAX_VALUE);//1.7976931348623157e+308
 console.log(Number.MIN_VALUE);//5e-324
 console.log(Number.MAX_SAFE_INTEGER);//9007199254740991
 console.log(Number.MIN_SAFE_INTEGER);//-9007199254740991

 //可以通过isFinite()来确定一个数值是不是有穷的,包含着隐式类型转换Number()
 console.log(isFinite(Infinity))//false

 //isNaN() 来判断这个数字是不是NaN,包含着隐式类型转换Number()
 console.log(isNaN('hello'));//true
 -0 === +0;//true;
 0 === -0;//true;
 0 === +0;//true
  1. 4 NaN

    NaN(not a number)它是表示本来要返回数值的操作失败了。NaN它有几个独特的特性,任何涉及到NaN的操作始终返回NaN,NaN不等于包括NaN在内的任何值。

    ECMAScript提供了**isNaN()**函数。它接受一个任意数据的参数判断这个参数是否“不是数值”。它会先把参数用number()方法转换一下。它虽然可以用来检测数字,但是它本意并不是用来检测数字,而是检查一个值是否为NaN。如果参数的结果为NaN,那它返回一个ture,如果参数不为NaN,则返回一个false。虽然不常见但是isNaN()也可以用于测试对象。

 var n = NaN;
 var s = 'davina';//这个地方先用number()方法转一下,再用isNaN()方法
 var n1 = 12;
 console.log(isNaN(n), isNaN(s), isNaN(n1));//true true false
  1. 5、转成数值

    有3个函数可以把非数值转换成数值:**Number()、parseInt()、parseFloat()。**其中Number()可以将任意类型的值转化成数值,而parseInt和parseFloat()只应用于字符串向数字的转换。Number()走的是v8引擎机制,parseInt/parseFloat()它是额外提供的方法,这二者是有根本上的区别。

  1. 5.1 Number([val])

Number([val])函数基于以下规则执行转换:

布尔值:true转换为1,false转换为0;

数值:直接返回;

null: 返回0;

undefined: 返回NaN;

字符串:把字符串转换为数字,只要字符串中包含任意一个非有效数字字符(第一个小数点除外)都会转成NaN。空字符串转成0。

对象:

    首先,调用对象的Valueof()方法,如果返回原始类型的值,则直接对该值使用Number();

    其次:如果Valueof()方法返回的还是对象,则调用对象的toString()方法,把它转成字符串后再使用使用Number();

    最后:如果toString()方法返回的依然是对象,则结果是NaN。

 总结:undefined转数字的结果是NaN;Null转数字的结果是0;true转数字的结果为1,false转数字的结果是0;空字符串,空格字符串转数字的结果为0,字符串里面的内容如果是纯数字就转成对应的数字,如果不是那结果为NaN;数字转数字的结果还是原来的数字;对象转数字不确定。

 console.log(Number(1));//1
 console.log(Number(true));//1
 console.log(Number(undefined));//NaN
 console.log(Number(NaN));//NaN
 console.log(Number(null));//0       
 //转字符串
 console.log(Number(''));//0
 console.log(Number(' '));//0
 console.log(Number('hello'));//NaN
 //转对象
 console.log(Number([]));   //0
 console.log(Number([1,2]));//NaN
// console.log(Number(其它对象)); //NaN
   
  1. 5.2 parseInt(string,radix)

    解析一个字符串并返回指定基数的十进制整数。string是要被解析的值,如果参数不是字符串,先用toString()方法转成字符串,从字符串左边开始查找,找到有效数字字符转换为数字,遇到非有效数字字符则停止查找。字符串最前面的空格被忽略,从第一个非空字符格字符开始转换。所以如果是parseInt(' ')则返回NaN。

    radix代表进制从2到36之间,表示被解析字符串的基数。它是可选。首先string这个字符串,他是把值看做是radix这个进制,然后转换为10进制的整数。如果parseInt遇到的字符不是指定radix参数中的数字,那么它将忽略这个字符以及所有后续字符并返回到该回扣款为止已解析的整数值。当radix它省略或者是为0时默认按照10进制处理(特殊:字符串以0x/oX开头,radix默认按照16进制处理)。

    经过parseInt()函数转换返回的结果是整数或者是NaN。

console.log(parseInt(' 1234'));//1234
console.log(parseInt(' 1234fa'));//1234
console.log(parseInt('  a1234ps'));//NaN
console.log(parseInt([1,3])); //1   [1,3].toString()=>'1,3'
console.log(parseInt(''),parseInt('  '),parseInt({}));//NaN NaN NaN
   

  
/*
 *意思是'2AF5'当做16进制,最后转成10进制
 * 现在要知道进制的转换:
 * 5*1+15*16^1+10*16^2+2*16^3=10997
 */
parseInt("2AF5", 16);//10997
/* 
 *3进制只能是0-2,所以查到3的时候,发现已经不是3进制的范围了,不再继续查找下去
 *意思是'2'当做3进制,最后转成10进制
 * 2*3^0 = 2
 */
parseInt("231", 3);//2
/* 
 * '234看做是5进制,转换为10进制'
 * 4+3*5+2*5*5=69
 */
parseInt('23461',5);//69
//radix不在2-36之间,最后结果为NaN
parseInt(1,1);//NaN
//radix省略或者为0时,默认按10进制处理
parseInt(1,0);//1
  
  1. 5.3 parseFloat(string)

    它是用于将字符串转换浮点数。string是需要被解析成为浮点数的值,返回被解析成的浮点数,如果给定值不能被转换成数值,则会返回NaN。它也是解析到字符串末尾或者是解析到一个无效的浮点数值字符为止。当第一次出现小数点它是有效的,但是第二次出现的小数点就无效了,字符串的剩余字符都会被忽略。

        console.log(parseFloat(' 1234ad'));//1234
        console.log(parseFloat(' 1234'));//1234
        console.log(parseFloat([1, 2]));//1
        console.log(parseFloat(true), parseFloat(false));//NaN NaN
        console.log(parseFloat([]), parseFloat([2.1]), parseFloat(['2.1px']));//NaN 2.1 2.1
        console.log(parseFloat({}), parseFloat(' '), parseFloat(''));//NaN NaN NaN 
  1. 6 Math

    它是是一个内置对象,具有数学常数和函数的属性和方法,常用的有**Math.ceil()、Math.floor()、Math.round()、Math.abs()、Math.random()**等等。下文来详细说明这几个方法的语法和用处。

    Math.ceil()把一个数向上取整。语法:Math.ceil() 参数就为一个数字,返回参数向上取整的数字;

    Math.floor()把一个数向下取整。语法:Math.floor() 参数就为一个数字,返回参数向上取整的数字;

    Math.round()把一个数四舍五入。语法:Math.round() 参数就为一个数字,返回四舍五入后的数字;

    Math.abs()求一个数的绝对值。语法:Math.abs() 参数就为一个数字,返回一个数字的绝对值;

    Math.random()取0-1之间的随机数(包括0不包括1)。语法:Math.random() 参数就为一个数字,返回一个0-1之间的随机数。

二、字符串

    字符串String是javascript基本数据类型,同时javascript也支持String对象,它是一个原始值的包装对象。在需要的时候javascript会自动在原始形式和对象形式之间进行转换。

    字符串类型常被用于表示文本数据。 字符串可以使用双引号(")、单引号(')或者是反引号(`)来标示。我们用某种引号作为开头那必须以这种引号作为字符串的结尾。

    javascript中的字符串是不可变的。一旦字符串被创建,就永远无法改变它。要改变某个变量保存的字符串,首先要销毁原来的字符串,然后再用另一个包含新值的字符串填充该变量。可以通过+运算符连接其他字符串来创建一个新字符串。

let firstName = 'lily';
let secondName = "amy";
let lastName = `tom`;
let errorName = 'error";// 这种是错误的开头和结尾引号要一样

2.1 转换字符

   把其实类型转换为字符串一般分为显示转换和隐式转换。显示转换有:String()和toString()。

    几乎每一个值都会有 toString()方法,它返回相应字符串。字符串也有toString()方法,这个方法只是简单地返回自身的一个副本。但是null和undefined值没有toString()方法。

    在很多情况下,toString()它不接收任何参数,但是在对数值调用这个方法时,toString()可 接收一个底数参数,默认情况下toString()返回数值的十进制字符串表示,但通过传入的参数可以得到数值的二进制,八进制或者是其他有效基数的字符串。

let num = 20;
console.log(num.toString(8));  //24
console.log(num.toString(16));  //14

  在我们不知道要转换的值是不是null或者是undefined时,可以使用String()方法。它始终会返回表示相应类型值的字符串。它遵循以下规则:

    如果值是null,则返回'null';

    如果值是undefined,则返回'undefined';

    如果值不是null或undefined,则调用toString()方法(不传参)并返回原始类型值;若使用toString()方法返回的是对象,则再调用valueOf()方法返回原始类型值,若使用valueOf()方法返回的是对象,会报错。

let value = 10;
let obj = {name:'lily'};
let n;
console.log(String(value)); //'10'
console.log(String(obj)); //'[object Object]'
console.log(String(n)); //'undefined'

    我们还可以使用空字符串“”+某个值,将该值转换为字符串。

 总之,undefined转字符串为'undefined'; Null转字符串为'null'; Number转字符串,把数字加上字符串; true转字符串'true',false转字符串'false'; String转字符串结果就是它本身; Object转字符串,给对象加上引号。

2.2 模板字符串

    ECMAScript6新增了模板字符串。模板字面量它可以保留换行字符,也可以跨行定义。顾名思义它在定义模板时特别的有用。它是包含特定语法的占位符。可以当作普通字符串,多行字符串,或者是字符串中嵌入变量使用。它最常用的特性就是字符串插件,字符串插值通过在${}中使用js表达式来实现。技术上来讲模板字符串它不是一个字符串,它是一种特殊的js句法表达式,只不过求值后得到字符串。

//字符串中嵌入了变量
let name = 'lily';
console.log(`my name is ${name}`);
//模板字符串中还可以调用函数
function hello(){return 'hello world!'};
console.log(`I want to say ${hello()}`);
//如果大括号内部是一个字符串,将会原样的输出
console.log(`hello ${'world'}`); // hello world
//模板也可以插入自己之前的值
let value = '';
function append(){
    value = `${value}say hi `;
    console.log(value);
};
append(); //say hi 
append(); //say hi say hi 
append(); //say hi say hi say hi 

三、Boolean类型

    Boolean类型表示逻辑实体,它是ECMAScript中使用最频繁的类型之一。有两个字面值true和false分别代表真和假这两个状态。这两个布尔值不同于数值,true不等于1,false不等于0。它主要是应用于条件和循环语句,逻辑运算符,关系运算符。

  要将其它值转换为布尔值可以调用Boolean()函数。 Boolean()转型函数它可以在任意类型的数据上调用,而且始终会返回一个布尔值。转换为false的值有''(空字符串)、0、NaN、null、undefined这4种类型5个值,其它转成布尔值为true(空格字符串转布尔值也为true)。

   逻辑运算符:!是取反的意思,因此加上两个!!两次取反后即得到本身的布尔值。

        //条件语句
        // if(a){
        //     条件为true时,执行这里的函数
        // }else{
        //     条件为false时,执行这里的函数
        // }

        //逻辑运算符 同时使用两个逻辑非操作符,可以将类型转换成布尔值
        console.log(!!1); //true
        console.log(!!0);//false
        console.log(!!'')//false
        console.log(!!" ");//true

        //转布尔值
        console.log(Boolean(undefined));//false
        console.log(Boolean(null));//false
        console.log(Boolean(NaN));//false
        console.log(Boolean(0));//false
        console.log(Boolean(''));//false
        console.log(Boolean(false));//false
        //注意:空字符串转为false,空格字符串转为true

四、Undefined类型

    Undefined类型只有一个值那就是它自身undefined,当声明的变量末初始化时,该变量的默认值是undefined,所以一般来说,undefined表示变量没有初始化。

    对于没有声明的变量只能执行一个操作,使用typeof操作符检测其数据类型,但严格模式下会导致错误。一般来说永远不要显式地给某个变量设置undefined值,字面量undefined它主要是用于和null(空对象指针)进行比较的。

    对于没有声明的变量只能执行一个操作那就是对它调用 typeof。对未初始化的变量调用typeof时,返回的结果'undefined',但是对末声明的变量调用typeof时它同样返回的是‘undefined’,这是因为严格来说虽然这两个变量存在根本性差异,但它们都无法执行实际操作。

let message;//声明变量message,但没有赋值
// let age;  要确保没有声明过这个变量
console.log(message);//'undefined'
console.log(age);//报错
console.log(typeof message);//'undefined'
console.log(typeof age); //'undefined'

五、Null类型

 Null类型只有一个值,就是null。它是javascript语言的关键字,它表示一个特殊的值,常用来描述为"空"。从逻辑的角度上来说,null表示为一个空对象指针。这也就是给typeof 传入一个null 会返回'object'的原因。在定义将来要保存对象值的变量时,可以使用null来初始化。

let age = null;
console.log(typeof age);//'object'

    尽管null和undefined不同,但它们都表示"值的空缺",null表示"空值",undefined表示"未定义"。等于操作符(==)认为两者是相等的。虽然它们有关系,甚至可以说undefined值是由null派生而来,但他们的用途完全不一样,我们永远不要显示地将变量值设置为undefined。但是在任何时候,只要变量要保存对象,而当时又没有那个对象可以保存,就要用到null来进行填充。

    我们可以用恒等来判断某个值是不是null。

console.log(null == undefined); //true
console.log('null' === null);  //false
console.log(null === null);  //true

六、Symbol类型

    Symbol是ECMASCript6新增的数据类型。它是原始值且实例唯一,不可变。可以确保对象属性使用唯一标识符,不会发生属性冲突。它用于创建唯一标记。

    我们在使用时要用到Symbol()函数被始化。因为它本身是原始类型,所以typeof操作符对它返回的是symbol。我们可以创建Symbol()实例并将它用作对象的新属性,这样就可以保证它不会覆盖已有的对象属性,无论是符号属性还是字符串属性。Symbol()它不能与new关键字一起作为构造函数使用。避免创建符号包装对象。

let sym = Symbol();
console.log(typeof sym);  //symbol
let otherSym = Symbol('other'); //可以传入字符串参数作为对符号的描述
console.log(otherSym); //Symbol(other)
let mySymbol = new Symbol(); // Uncaught TypeError: Symbol is not a constructor

七、 BigInt

    BigInt是一种内置对象,它是js中可以用Number表示的最大数字。BigInt可以表示任意大的整数。

    我们可以在一个整数字面量后面加n的方式定义一个BigInt或者是调用BigInt()函数。

const theBiggestInt = 9007199254740991n;
const alsoHuge = BigInt(9007199254740991);

    它虽然在某些方面上类似于Number,但是它不能用Math对象中的方法,不能和任何Number实例混合运算,两者必须转换成同一种类型。使用typeof测试时,BigInt对象返回‘bigint’。它和Number不是严格相等的,但宽松相等。

typeof 2n === 'bigint';  //true
typeof BigInt('1') === 'bigint';  //true
0n === 0;  //false
0n == 0;  //true