[js] 数据类型

本文深入解析JavaScript中的七种基本数据类型:null、undefined、boolean、number、string、object及symbol的特点与应用。针对number类型讨论了整数和浮点数的区别,以及ES6中解决浮点数精度问题的方法。同时介绍了字符串、数组、Set、WeakSet、Map和WeakMap等复合数据类型的使用技巧,并提供了数组去重、并集、交集和差集的实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

my git

基本数据类型共七种

  • null
  • undefined
  • boolean
  • number
  • string
  • object
  • symbol

null

typeof null === 'object' // 早期js判断空指针问题
// 判断null
a === null
!a && typeof a === 'object'

typeof null
typeof null history

undefined

boolean

基本类型通过装箱,可以实现类似数组的功能

number

整数和浮点数都为number格式
浮点数采用 IEEE 754 编码,有精度问题

0.1 + 0.2 === 0.3 // false

ES6中采用Nubmer.EPSILON定义机器精度

function fixedEqual (a, b) {
  return Math.abs(a - b) < Number.EPSILON;
}
fixedEqual(0.1 + 0.2, 0.3); // ture

.优先级比运算高

42.toFixed(2); // SyntaxError: Invalid or unexpected token
42..toFixed(2); // 42.00

整数范围可以达到2^53 - 1, 但是位运算只能达到2^32

var n = Math.pow(2, 53); // 在chrome中实际上可以达到。。。
n >> 2; // 0

NaN是唯一一个不等于自身的数

NaN !== NaN // true

string

字符串本身不能改变,每次赋值会生成一个新字符串重新赋值

var s = '123';
s.concat('4'); // '1234'
// 类似数组,可以用硬绑定实现数组功能
Array.prototype.map.call(s, (i) => {
  console.log(i);
}); // 1 2 3
// 但是字符串本身不能改变
Array.prototype.reverse.call(s); // TypeError: Cannot assign to read only property '0' of object '[object String]'
a.split('').reverse().join(''); // '321'

object

symbol

对象
变量,对象

数组
数组

set
mdn set
set类似于数组,但成员值唯一,没有重复值

const s = new Set();
[1, 1, 2, 2, 6, 6].forEach(x => s.add(x));
s; // Set(3) {1, 2, 6}
s.entries(); // SetIterator {1, 2, 6}

set函数可以接受具有iterable接口的所有数据结果作为参数来初始化
set不发生类型转换,内部判断值是否相同采用“Same-value equality”算法,类似于“===”,区别在于NaN是否等于自身;不同的对象总不相等,引用除外

var s = new Set();
var a = {};
[1, '1', 2, '2', NaN, NaN, {}, {}, a, a].forEach(i => s.add(i));
s; // Set(8) {1, "1", 2, "2", NaN, Object, Object, Object}

set的遍历可采用keys(),values(),entries(),由于set没有键名,所以keys和values方法行为一致。
set结构实力默认可遍历,其遍历生成函数就是其values方法。

Set.prototype[Symbol.iterator] // function values() { [native code] }

tips
数组去重

var arrNew = [...new Set(arrOri)];
var arrNew = Array.from(new Set(arrOri));

并集交集差集

var a = new Set([1, 2, 3, 4]);
var b = new Set([2, 4, 6, 8]);
var union = new Set([...a, ...b]);
var intersection = new Set([...a].filter(i => b.has(i)));
var difference = new Set([...a].filter(i => !b.has(i)));
union; // Set(6) {1, 2, 3, 4, 6, 8}
intersection; // Set(2) {2, 4}
difference; // Set(2) {1, 3}

WeakSet
mdn weakset
WeakSet成员只能是对象

var a = {};
var b = 1;
var c = [[1, 2], [3, 4]];
var d = [1, 2];
var ws0 = new WeakSet();
// 可用一个iterable数据初始化
var ws1 = new WeakSet(c);
var ws2 = new WeakSet(d); // Uncaught TypeError: Invalid value used in weak set
ws0.add(a); // ws0.add(a);
ws0.add(b); // Uncaught TypeError: Invalid value used in weak set
ws0.add(d); // WeakSet {Object {}, [1, 2]}
ws1; // WeakSet {[3, 4], [1, 2]}

WeakSet均是弱引用,所以垃圾回收机制不考虑WeakSet对该对象的引用
WeakSet适合存放临时对象,不可遍历
tips
保证实例方法只能被实例调用

const foos = new WeakSet()
class Foo {
  constructor() {
    foos.add(this)
  }
  method () {
    if (!foos.has(this)) {
      throw new TypeError('Foo.prototype.method 只能在Foo的实例上调用!');
    }
  }
}

map
mdn map
map类似与对象,但是map的键不限于字符串,各种类型的值(包括对象)均可作为键

const m = new Map();
let o = {};
m.set(o, 'what');
m.get(o); // 'what'
m[o]; // undefined
o.a = 1;
m.get(o); // 'what'
o = {a:1};
m.get(o); // undefined

map的遍历顺序就是插入顺序
map的默认遍历器接口是entries方法

WeakMap
mdn weakmap
WeakMap只接受对象作键名(null除外)
WeakMap键名指向的对象不计入垃圾回收机制,键值仍是正常引用
WeakMap没有遍历操作和size属性,不支持clear方法

参考
阮一峰 ES6

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值