首页 前端知识 JS 数据类型

JS 数据类型

2024-10-15 23:10:37 前端知识 前端哥 569 947 我要收藏

文章目录

  • JavaScript 八种数据类型
  • 一、Number
    • 1.1、整数
    • 1.2、浮点数
    • 1.3、数值范围
    • 1.4、NaN
    • 1.5、数值转换
  • 二、String
    • 2.1、 字符字面量(转义序列)
    • 2.2、转换为字符串
  • 2.3、模板字符串
  • 三、Boolean
    • 3.1、 布尔值转换
  • 四、Undefined
  • 五、Null
  • 六、Symbol
    • 6.1、实例:Symbol 值作为对象的属性名
    • 6.2、方法 Symbol.for(key)
    • 6.3、方法 Symbol.keyFor(symbol)
  • 七、BigInt
    • 7.1、运算
    • 7.2、注意点
  • 八、Object
    • 8.1、创建对象
    • 8.2、对象属性存取
    • 8.3、拓展

JavaScript 八种数据类型

JavaScript 目前包含八种数据类型,其中可以分成两大类。

①基本数据类型(原始值):

Number(数值,包含NaN)
String(字符串)
Boolean(布尔值)
Undefined(未定义/未初始化)
Null(空对象)
Symbol(独一无二的值,ES6 新增)
BigInt (大整数,能够表示超过 Number 类型大小限制的整数,ES 2020新增)

②引用数据类型(引用值):

Object(对象。Array/数组 和 function/函数 也属于对象的一种)

③区别

基本数据类型的值是不可变的,你无法修改值本身,你只能给代表它的变量重新赋值,将原来的值覆盖。而引用数据类型是可变的,它们的值是可修改的。

一、Number

Number 类型包括整数和浮点数值。也支持不同进制的表示方式。

1.1、整数

十进制

let intNum = 666; // 整数

八进制:

八进制的值第一位必须是零0,后面每一位数的范围在0~7。如果某一位数超出范围,首位的0会被忽略,后面的数值会按照十进制来解析

let octalNum1 = 070; // 八进制的 56 
let octalNum2 = 079; // 无效的八进制数值——解析为 79 
let octalNum3 = 08; // 无效的八进制数值——解析为 8 

十六进制:

十六进制的值前两位必须是0x,后面每一位十六进制数字的范围在09及AF,字母A~F可以大写也可以小写。

let hexNum1 = 0xA; // 十六进制的 10 
let hexNum2 = 0x1f; // 十六进制的 31

进行算术运算时,所有八进制和十六进制的数值都会被视为十进制。

1.2、浮点数

浮点数的数值中必须包含一个小数点,并且小数点后面必须至少有一位数字。如果小数点后面没有数字,或者本身表示的就是有一个整数(例如1.0),那么该值会被转换为整数保存。

let floatNum1 = 1.1; 
let floatNum2 = 1.; // 小数点后面没有数字——解析为 1 
let floatNum3 = .1; // 有效,但不推荐
let floatNum4 = 10.0; // 整数——解析为 10 

对于那些极大或极小的数值,可以用e表示法(即科学计数法)来表示。e后面的数字代表10的幂中的指数,该幂值用来与前面的数相乘。例子:

let floatNum1 = 6.123e7; // 等于61230000
let floatNum2 = 3e-17; // 等于0.00000000000000003

浮点数值的最高精度是17位小数,但是进行算数运算时是有误差的。例如:

let a = 0.1;
let b = 0.2;
console.log(a + b); // 结果是 0.30000000000000004

因此,应该要避免以下例子的测试:

if (a + b == 0.3) { 
	// ...do something
}

要解决这个问题,可以使用如下方法对浮点数进行加减运算

export function addNum(num1, num2) {
  let sq1, sq2, m;
  try {
    sq1 = num1.toString().split(".")[1].length;
  } catch (e) {
    sq1 = 0;
  }
  try {
    sq2 = num2.toString().split(".")[1].length;
  } catch (e) {
    sq2 = 0;
  }
  m = Math.pow(10, Math.max(sq1, sq2));
  return (num1 * m + num2 * m) / m;
}

还可以使用 toFixed() 方法对计算结果进行四舍五入:

console.log((0.1 + 0.2).toFixed(1)); // 0.3
console.log(((0.28 * 100 + 0.14 * 100) / 100).toFixed(2)); // 0.42
// 要注意的是 toFixed() 方法返回的是字符串,如果是将计算结果展示到页面上是很方便的。
// 如果是需要数值的情况,还要进行类型转换操作,例如使用"+"将其转换为数值:
console.log(+(0.1 + 0.2).toFixed(1)); // 0.3
console.log(typeof +(0.1 + 0.2).toFixed(1)) // number

1.3、数值范围

由于内存限制,JavaScript不能保存所有的数值。如果某次计算的结果得到了一个超出 JavaScript数值范围的值,那么这个数值将被自动转换成特殊的 Infinity 值。具体来说,如果这个数值是负数,则会被转换成-Infinity(负无穷),如果这个数值是正数,则会被转 换成 Infinity(正无穷)。
image.png

1.4、NaN

NaN,即非数值(Not a Number),这是一个特殊的数值,拥有以下两个特点:

  • 任何涉及 NaN 的计算(例如 NaN/10)都会返回 NaN。
  • NaN 与任何值都不相等,包括 NaN 本身。

鉴于NaN不等于自身,可以使用 isNaN() 全局函数来判断一个值是否是 NaN 值。
该函数会对传入的参数尝试使用Number()转换为数值,任何不能被转换为数值的值都会导致该函数返回true。

console.log(isNaN(NaN));         // true 
console.log(isNaN(10));          // false(10是一个数值) 
console.log(isNaN("10"));        // false(可以被转换成数值 10) 
console.log(isNaN("blue"));      // true(不能转换成数值) 
console.log(isNaN(true));        // false(可以被转换成数值 1)

1.5、数值转换

Number():把任何数据类型的值转换为数值
parseInt():把字符串转换为整数值
parseFloat():把字符串转换为浮点数值

Number、parseInt、parseFloat转整数的区别

二、String

字符串可以用双引号( " )、单引号(')或反引号(`)标识。以下三种形式都是合法的:

let name1 = "小明";
let name2 = '小明';
let name3 = `小明`;

2.1、 字符字面量(转义序列)

String 类型包含一些特殊的字符字面量,也叫转义序列,用于表示非打印字符,或者具有其 他用途的字符。这些字符字面量可以出现在字符串中的任意位置,而且也将被作为一个字符来解析。

image.png

2.2、转换为字符串

  • toString():这是一个方法,数值、布尔值、对象和字符串都有toString()方法。null和undifined都没有toString()方法
  • String():这是一个全局函数,适用于所有数据类型

2.3、模板字符串

模板字符串相当于加强版的字符串,可以定义多行字符串。还可以利用${}在字符串中插入变量和表达式。

let s1 = `hello
world!`;
console.log(s1); 
// "hello"
// "world!"

let myName = '小明';
let s2 = `我叫${myName}`;
console.log(s2); 
// "我叫小明"

let s3 = `我今年${2020-2010}岁`;
console.log(s3); 
// "我今年10岁"

三、Boolean

Boolean 类型只有两个字面值:true 和 false。

3.1、 布尔值转换

其他 ECMAScript 类型的值都有与布尔值等价的形式。
可以调用 Boolean() 函数来将其他类型转换为布尔值。
不同类型转换为布尔值的规则如下表:

image.png

四、Undefined

Undefined 类型只有一个值,即undefined。在声明变量但是没有初始化时,这个变量的值就是undefined。

正常情况下,调用未声明的变量会报错,但是对未声明的变量使用typeof操作符,同样会返回"undefined",例如:

var myName;
// age 未声明
// var age;
console.log(typeof myName); // "undefined"
console.log(typeof age); // "undefined"

五、Null

Null 类型也是只有一个值,即null。null表示指向一个空对象的指针,因此使用 typeof 操作符检测 null 值时会返回"object"

let car = null;
console.log( typeof car ); // "object"

六、Symbol

Symbol 是 ES6 中引入的新基本类型,表示独一无二的值。Symbol 值通过 Symbol() 函数生成。

let s = Symbol();
console.log(typeof s) // "symbol"

该函数可以接受一个字符串作为参数,表示对 Symbol 实例的描述,使得在控制台显示,或者转换为字符串进行判断时容易区分。

let s1 = Symbol('foo');
let s2 = Symbol('bar');

console.log(s1) // "Symbol(foo)"
console.log(s2) // "Symbol(bar)"

if ( s1.toString() === "Symbol(foo)" ) {
    // do something...
}

注意, Symbol() 函数的参数只有描述作用,即使两个 Symbol() 函数的参数相同 ,它们的返回值也是不相等的。

6.1、实例:Symbol 值作为对象的属性名

因为每一个 Symbol 值都是不相等的,所以 Symbol 值可以用作唯一标识,用于对象的属性名,就能防止属性名的同名冲突。对于一个对象是由多个模块构成的情况下非常有用,避免某个 key 被改写或者覆盖。

let s = Symbol();

// 写法一
let a = {};
a[s] = 'Hello!';

// 写法二
let a = {
  [s]: 'Hello!'
};

console.log(a[s]); // "Hello!"

注意,Symbol 值作为对象属性名时,不能用点运算符,需要用中括号运算符。否则对象a的属性名s会被认为是一个字符串而不是一个 Symbol 值。

同理,在对象的内部使用 Symbol 值定义属性时,Symbol 值也必须放在方括号之中(参考以上代码写法二)。

6.2、方法 Symbol.for(key)

该方法和Symbol()都能生成新的 Symbol,区别是Symbol.for将这个Symbol 注册到全局 而Symbol()不会。

Symbol.for() 调用不会直接生成新的Symbol,它会先从注册表中搜索给定的key是否存在。如果存在,那么返回的是同一个 Symbol,否则生成新的。

let s1 = Symbol.for('foo');
let s2 = Symbol.for('foo');

s1 === s2 // true

6.3、方法 Symbol.keyFor(symbol)

该方法返回一个已注册的 Symbol 类型值的key。

// 创建一个 symbol 并注册,key 为 "foo"
let s1 = Symbol.for("foo");
Symbol.keyFor(s1) // "foo"

// 创建一个 symbol 但不注册,注册表中找不到该symbol 的 key
let s2 = Symbol("foo");
Symbol.keyFor(s2) // undefined

七、BigInt

BigInt 是 ES 2020 新增的基本类型,能够表示任意长度的整数,突破了 Number 类型的大小限制问题。

要定义一个 BigInt ,可以在整数字面量加上n的后缀,或者调用BigInt()函数。

let b1 = 10n;
let b2 = 9007199254740991n;
let b3 = BigInt(Number.MAX_SAFE_INTEGER); 
let b4 = BigInt(Number.MIN_SAFE_INTEGER);
let b5 = BigInt("0x1fffffffffffff");

console.log(b1); // 10n
console.log(b2); // 9007199254740991n
console.log(b3); // 9007199254740991n
console.log(b4); // -9007199254740991n
console.log(b5); // 9007199254740991n

上面例子中的 Number.MAX_SAFE_INTEGERNumber.MIN_SAFE_INTEGER 表示最大和最小安全整数,如果是Number 类型数值超过此范围都可能会失去精度。

console.log(9999999999999999) // 10000000000000000

7.1、运算

BigInt 支持除单目+运算符以外的算数运算符。

console.log(10n + 10n); // 20n
console.log(11n - 10n); // 1n
console.log(2n * 10n); // 20n
console.log(110n / 10n); // 11n
console.log(10n ** 3n); // 1000n
console.log(101n % 10n); // 1n

console.log(-10n); // -10n
console.log(+10n); // 报错

BigInt 运算结果如果有小数则会被向下取整。

console.log(5n / 2n); // 2n, 而非2.5n

7.2、注意点

BigInt 虽然在一些方面类似 Number,但也有一些需要注意的地方:

  • 不能用 Math 对象中的方法。
  • 不能和 Number 类型数值进行混合算术运算,必须转换成同一类型。
  • 虽然 BigInt 不能和 Number 直接进行算术运算,但使用比较运算符(==、<、>等等)直接比较是允许的。
  • BigInt 转换为 Number 可能会丢失精度。

八、Object

对象是一组数据和方法的无序集合,所有实例的基础是Object 类型。

8.1、创建对象

  • 第一种是使用 new 操作符和 Object 构造函数:
let person = new Object(); // 创建了一个空对象
person.name = "小明"; // 往对象中添加属性
person.age = 20;

  • 第二种方式是使用对象字面量表示法,能够简化对包含大量属性的对象的创建,看起来也更加一目了然:
let person = {
	name: "小明",
	age: 20
};

以上两种方式是等效的,但是要注意

  • 在使用对象字面量的方式定义对象时,并不会实际调用 Object 构造函数。
  • 另外,对象字面量法中,对象属性名也可以用字符串或者数值,若是数值属性则会自动转换为字符串。
let person = {
	"name": "小明",
	"age": 20,
    5: true
};

8.2、对象属性存取

对象的属性一般是通过点语法来进行存取,但是也可以用中括号来存取属性。使用中括号时,要在中括号内使用属性名的字符串形式,例如:

console.log(person.name); // "小明"
console.log(person["name"]); // "小明"

通常,点语法是首选的存取方式,必须使用中括号语法的情况有:

  • 需要通过变量来访问属性。
  • 属性名中包含可能会导致语法错误的字符,例如关键字/保留字、空格等。
  • 属性名是数值
let propertyName = "name";
console.log(person[propertyName]); // "小明"

person["my name"] = "小明";

person[5] = false;

8.3、拓展

对象大致可分为三类:

  • 内置对象:由 ECMAScript 定义的对象,例如Array、Math、Date。
  • 自定义对象:通过构造函数或者字面量创建的对象。
  • 宿主对象:由执行环境提供的对象,例如浏览器环境的DOM和BOM中的对象

Object 的每个实例都具有以下属性和方法:

  • constructor:指向构造函数。
  • hasOwnProperty(propertyName):检查某个属性是否在当前对象实例中(而不是在实例的原型中)。参数必须为字符串形式。
  • isPrototypeOf(object):用于检查调用对象是否是传入对象的原型。
  • propertyIsEnumerable(propertyName):用于检查某个属性是否能够使用 for-in 语句来枚举。参数必须为字符串形式。
  • toLocaleString():返回对象的字符串表示,该字符串与执行环境的地区对应。JavaScript 的一些内置对象都重写了该函数,以实现更适合自身的功能需要。
  • toString():返回对象的字符串表示。
  • valueOf():返回对象的字符串、数值或布尔值表示。通常与 toString()方法的返回值相同。

ECMAScript 中对象的行为不一定适用于 JavaScript 中的其他对象。 例如宿主对象不是由 ECMAscript 定义的,因此宿主对象不一定会继承 Object。

转载请注明出处或者链接地址:https://www.qianduange.cn//article/18995.html
标签
评论
发布的文章

安装Nodejs后,npm无法使用

2024-11-30 11:11:38

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!