ES6 对象和数值扩展:Object.assign、Object.keys、Number 新方法。
核心四个:
① Object.assign()——合并对象
② Object.keys() / values() / entries()——拿键/值/键值对
③ Number.isFinite() / Number.isNaN()——比全局的更严格
④ Number.parseInt / parseFloat——替代全局
坑:Object.assign 是浅拷贝、Object.keys 返回数组、Number.isNaN 只判断 NaN。
=== 平时够用,但它对两个特殊情况很"糊涂":它觉得 NaN === NaN 是 false,还觉得 0 === -0 是 true。Object.is 就是来纠正这两点的。
// false(=== 糊涂了) console.log(NaN === NaN); // true ← 较真:NaN 等于 NaN console.log(Object.is(NaN, NaN)); // true (=== 觉得 ±0 一样) console.log(0 === -0); // false ← 较真:0 不等于 -0 console.log(Object.is(0, -0));
如果你平时只是想判断两个值相不相等,用 === 就够了。只有两种场景才需要 Object.is:要判断的可能是 NaN,或者要区分 +0 和 -0。
想象你有一份"默认配置",用户又传了一份"自定义配置",想把后者盖到前者上——Object.assign(目标, 源1, 源2...) 就是干这个的。
// 先有个目标对象(默认配置)
let target = { a: 1 };
// 以前:一个个手动加
// 手动加 b
target.b = 2;
// 手动加 c
target.c = 3;
// 现在:一次把多个源对象的属性并进目标
// 把后面两个源对象挨个倒进 target
Object.assign(target, { b: 2 }, { c: 3 });
// ^^^^^^ ^^^^^^^^ ^^^^^^^^
// 加到这 来自源1 来自源2
// {a:1, b:2, c:3}
console.log(target);
Object.assign(目标, 源1, 源2...) 会把后面所有源对象的属性逐个"并"进目标;同名属性后面的覆盖前面的。做"默认配置 + 用户配置"合并时最常用——用户没传的项用默认,传了的项盖掉默认。
以前写二进制、八进制容易写错,ES6 给了明确的前缀:0b 是二进制,0o 是八进制,0x 是十六进制。
// 10(0b 开头是二进制) console.log(0b1010); // 15(0o 开头是八进制) console.log(0o17); // 31(0x 开头是十六进制) console.log(0x1f);
全局的 isNaN 是个"老好人",会偷偷把传进来的东西先转成数字再判断;Number.isNaN 不转类型,老老实实只认真正的 NaN。
// 全局 isNaN:宽松,先偷偷转类型
// true("abc" 被转成 NaN 了)
console.log(isNaN("abc"));
// Number.isNaN:严格,不转类型
// false("abc" 根本不是 NaN)
console.log(Number.isNaN("abc"));
// false(不是整数)
console.log(Number.isInteger(3.5));
// 3(直接砍掉小数部分,不四舍五入)
console.log(Math.trunc(3.9));
如果你用全局 isNaN("abc") 判断"这是不是一个 NaN",得到 true 就会被误导——它其实是因为 "abc" 转不成数字才 true 的。判断是不是真 NaN 用 Number.isNaN,判断整数用 Number.isInteger,砍小数用 Math.trunc。
① 可能在什么地方用:合并默认配置与用户配置(Object.assign)、判断两个值是否严格相同(特殊情况用 Object.is)、表单校验是否整数(Number.isInteger)、取整(Math.trunc)。
② 常见的问题:用全局 isNaN 把字符串误判成 NaN;Object.assign 直接改了原对象(目标和源传成同一个);把 Math.trunc 当成四舍五入。
③ 解决思路:要纯判断就用 Number.isNaN;合并时目标传一个空对象 {} 避免污染源;要四舍五入用 Math.round,Math.trunc 只负责砍小数。
| API | 作用 | 参数 | 返回值 | 代码示例 |
|---|---|---|---|---|
| Object.is(a, b) | 更较真地比较:认 NaN、区分 +0/-0 | 两个值 | true / false | Object.is(NaN, NaN); |
| Object.assign(t, s) | 把后面源对象的属性合并到目标上 | 目标, 源对象... | 目标对象 | Object.assign(o, { a: 1 }); |
| Number.isNaN(x) | 严格判断是不是 NaN(不误判字符串) | 一个值 | true / false | Number.isNaN("x"); |
| 0b / 0o / 0x | 二/八/十六进制写法,值不变 | 数字 | 数字 | 0b1010; // 10 |