Skip to content

js 中的基本类型和隐式转换

基本类型

在 JavaScript 中,基本类型(基本数值、基本数据类型)是一种既非对象也无方法属性的数据。有 7 种原始数据类型:

  • string
  • number
js
它能够存储 2^-1074(Number.MIN_VALUE)和 2^1024(Number.MAX_VALUE)之间的正浮点数;
以及 -2^-1074-2^1024 之间的负浮点数;
但是它仅能安全地存储在 -(2^531)(Number.MIN_SAFE_INTEGER)到
 2^531(Number.MAX_SAFE_INTEGER)范围内的整数。
超出这个范围,JavaScript 将不能安全地表示整数;
相反,它们将由双精度浮点近似表示。
可以使用 Number.isSafeInteger() 检查一个数是否在安全的整数范围内。
  • bigint
js
BigInt 类型在 Javascript 中是一个数字的原始值,它可以表示任意大小的整数。
使用 BigInt,你可以安全地存储和操作巨大的整数,
甚至超过 Number 的安全整数限制(Number.MAX_SAFE_INTEGER)。

let bigNumber = BigInt("1000000000000000000000");
let bigNumberString = bigNumber.toString();
console.log(bigNumberString); // 输出 "1000000000000000000000"
  • boolean
  • undefined
  • symbol
js
Symbol 是唯一并且不可变的原始值并且可以用来作为对象属性的键(如下)。
在某些程序语言当中,Symbol 也被称作“原子类型”(atom)。
***symbol 的目的是去创建一个唯一属性键,保证不会与其它代码中的键产生冲突。***
  • null

所有基本类型的值都是不可改变的。但需要注意的是,基本类型本身和一个赋值为基本类型的变量的区别。变量会被赋予一个新值,而基本类型不能像数组、对象以及函数那样被改变。

基本类型没有方法,但仍然表现得像有方法一样。当在基本类型上访问属性时,JavaScript 自动将值装入包装器对象中,并访问该对象上的属性。 例如,"foo".includes("f") 隐式创建了一个 String 包装对象,并在该对象上调用 String.prototype.includes()。这种自动装箱行为在 JavaScript 代码中是无法观察到的,但却是各种行为的一个很好的心理模型——例如,为什么“改变”基本类型不起作用(因为 str.Foo = 1 不是赋值给 str 本身的 Foo 属性,而是赋值给了一个临时包装器对象)。【间接证明 js 是弱类型语言】

参考

引用类型

  • Object
js
在计算机科学中,对象(object)是指内存中的可以被标识符引用的一块区域。
在 JavaScript 中,对象是唯一可变 (en-US)的值。
事实上,函数也是具有额外可调用能力的对象

数据类型typeof返回值

类型typeof 返回值对象包装器
单元格单元格单元格
单元格单元格单元格
Null"object"N/A
Undefined"undefined"N/A
Boolean"boolean"Boolean
Number"number"Number
BigInt"bigint"BigInt
String"string"String
Symbol"symbol"Symbol

隐式转换

掘金贴

  • 运算符:如果运算对象是字符串,执行字符串串联;否则,执行数值相加;
  • ==运算符:如果其中一个操作数是对象,另一个是基本类型,按此顺序使用对象的 @@toPrimitive()(以 "default" 作为提示),valueOf()toString() 方法将对象转换为基本类型。(这个基本类型转换与相加中使用的转换相同

看一些例子:

  • 有类型转化的比较
js
"1" == 1; // true
1 == "1"; // true
0 == false; // true
0 == null; // false
0 == undefined; // false
0 == !!null; // true, 看看逻辑非运算符
0 == !!undefined; // true, 看看逻辑非运算符
null == undefined; // true

const number1 = new Number(3);
const number2 = new Number(3);
number1 == 3; // true
number1 == number2; // false
  • 比较对象
js
const object1 = {
  key: "value",
};

const object2 = {
  key: "value",
};

console.log(object1 == object2); // false
console.log(object1 == object1); // true
  • 比较字符串和 String 对象:请注意,使用构造的字符串 new String() 是对象。如果将其中之一与字符串文字进行比较,则该 String 对象将被转换为字符串文字并对其内容进行比较。但是,如果两个操作数都是 String 对象,则将它们作为对象进行比较,并且必须引用相同的对象才能进行比较
js
const string1 = "hello";
const string2 = String("hello");
const string3 = new String("hello");
const string4 = new String("hello");

console.log(string1 == string2); // true
console.log(string1 == string3); // true
console.log(string2 == string3); // true
console.log(string3 == string4); // false
console.log(string4 == string4); // true
  • 比较数组和字符串
JS
const a = [1, 2, 3];
const b = "1,2,3";
a == b; // true, `a` converts to string

const c = [true, 0.5, "hey"];
const d = c.toString(); // "true,0.5,hey"
c == d; // true

参考

运算符

  • 可选链运算符 ?.:在引用为空 (nullish ) (null 或者 undefined) 的情况下不会引起错误,该表达式短路返回值是 undefined。与函数调用一起使用时,如果给定的函数不存在,则返回 undefined。(可选链不能用于赋值)
js
const adventurer = {
  name: "Alice",
  cat: {
    name: "Dinah",
  },
};

const dogName = adventurer.dog?.name;
console.log(dogName);
// Expected output: undefined

console.log(adventurer.someNonExistentMethod?.());
// Expected output: undefined


// !!!可选链不能用于赋值
let object = {};
object?.property = 1; // Uncaught SyntaxError: Invalid left-hand side in assignment
  • 空值合并运算符 ??:空值合并运算符可以在使用可选链时设置一个默认值。
js
let customer = {
  name: "Carl",
  details: { age: 82 },
};
let customerCity = customer?.city ?? "暗之城";
console.log(customerCity); // “暗之城”

Released under the MIT License.