Notes
js 常用整理
toLocaleString()
说明
toLocaleString()方法返回这个数字在特定语言环境下的表示字符串。- 语法:
numObj.toLocaleString([locales [, options]])
let number = 123456789;
number.toLocaleString(); // 123,456,789
number = 12345.6784;
number.toLocaleString(); // 12,345.678
number = 12345.6785;
number.toLocaleString(); // 12,345.679
// nu 扩展字段要求编号系统,e.g. 中文十进制
number.toLocaleString("zh-Hans-CN-u-nu-hanidec"); // 一二三,四五六.六七九
Math 常用的属性方法
Math 不是一个构造器。Math 的所有属性与方法都是静态的。Math.PI
Math.PI表示一个圆的周长与直径的比例,约为 3.14159。Math.abs()
Math.abs()函数返回给定数字的绝对值。Math.abs("-1"); // 1
Math.abs(-2); // 2
Math.abs(null); // 0
Math.abs("string"); // NaN
Math.abs(); // NaN
Math.ceil()
Math.ceil()函数返回大于或等于一个给定数字的最小整数。既向上取整。Math.ceil(0.95); // 1
Math.ceil(1.05); // 2
Math.ceil(-1.05); // -1
Math.ceil(1); // 1
Math.floor()
Math.floor()返回小于或等于一个给定数字的最大整数。既向下取整。Math.floor(45.95); // 45
Math.floor(45.05); // 45
Math.floor(45); // 45
Math.floor(-45.05); // -46
Math.floor(-45.95); // -46
Math.max()
Math.max()函数返回一组数中的最大值。如果给定的参数中至少有一个参数无法被转换成数字,则会返回NaN。如果没有参数,则结果为 -Infinity。Math.max(); // -Infinity
Math.max(3, -1, 1, 2, 3, 4, 5); // 5
Math.max(3, -1, 1, 2, 3, 4, 5, "", false); // 5
Math.max(3, -1, 1, 2, 3, 4, 5, "", false, undefined); // NaN
const arr = [3, -1, 1, 2, 3, 4, 5];
Math.max.apply(null, arr); // 5
Math.max(...arr); // 5
Math.min()函数返回一组数中的最小值。如果给定的参数中至少有一个参数无法被转换成数字,则会返回NaN。如果没有参数,结果为 Infinity。Math.min(); // Infinity
Math.min(3, -1, 1, 2, 3, 4, 5); // -1
Math.min(3, -1, 1, 2, 3, 4, 5, "", false); // -1
Math.min(3, -1, 1, 2, 3, 4, 5, "", false, undefined); // NaN
const arr = [3, -1, 1, 2, 3, 4, 5];
Math.min.apply(null, arr); // -1
Math.min(...arr); // -1
Math.pow()
Math.pow(x, y)函数返回基数 x 的指数 y 次幂,即 xy。等价于 x**y。Math.pow(2, 10); // 1024
2 ** 10; // 1024
Math.pow(4, 0.5); // 2
Math.pow(4, -0.5); // 0.5
Math.pow(-7, 0.5); // NaN
Math.random()
Math.random()函数返回一个浮点数, 伪随机数在范围从 0 到小于 1,也就是说,从 0(包括 0)往上,但是不包括 1(排除 1),然后您可以缩放到所需的范围。Math.random();
Math.floor(Math.random() * 3);
Math.round()
Math.round()函数返回一个数字四舍五入后最接近的整数。Math.round(20.49); // 20
Math.round(20.5); // 21
Math.round(-20.5); // -20
Math.round(-20.51); // -21
Math.round(-20.49); // -20
Math.sqrt()
Math.sqrt()函数返回一个数的平方根。y^2 = x。如果参数 number 为负值,则返回 NaN。Math.sqrt(9); // 3
Math.sqrt(2); // 1.414213562373095
Math.sqrt(1); // 1
Math.sqrt(0); // 0
Math.sqrt(-1); // NaN
Math.sqrt(-0); // -0
Math.trunc()
注意
Math.trunc()函数会将数字的小数部分去掉,只保留整数部分。等价于 ~~(无 +0、-0 区分)。Math.trunc()的执行逻辑很简单,仅仅是删除掉数字的小数部分和小数点,不管参数是正数还是负数。传入该方法的参数会被隐式转换成数字类型。
Math.trunc(13.37); // 13
Math.trunc(42.84); // 42
Math.trunc(0.123); // 0
Math.trunc(-0.123); // -0
Math.trunc("-1.123"); // -1
Math.trunc(Number.NaN); // NaN
Math.trunc("foo"); // NaN
Math.trunc(); // NaN
~~-0.95; // 0
~~0.95; // 0
~~-1.05; // -1
~~-1.95; // -1
~~45.95; // 45
~~45.05; // 45
Object 常用的属性方法
Object.assign()
用于将所有可枚举属性的值从一个或多个源对象分配到目标对象。它将返回目标对象。
const o1 = { a: 1 };
const o2 = { b: 2 };
const o3 = { c: 3 };
const obj = Object.assign(o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
console.log(o1); // { a: 1, b: 2, c: 3 }
Object.defineProperty()
直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
const obj = {}; // 创建一个新对象
// 在对象中添加一个属性与数据描述符的示例
Object.defineProperty(obj, "a", {
value: 37,
writable: true,
enumerable: true,
configurable: true,
});
Object.defineProperties()
- 直接在一个对象上定义新的属性或修改现有属性,并返回该对象。
- 该方法与Object.defineProperty相似,只不过该方法可以一次性操作多个属性。
const obj = {};
Object.defineProperties(obj, {
property1: {
value: true,
writable: true,
},
property2: {
value: "Hello",
writable: false,
},
});
// {property1: true, property2: 'Hello'}
Object.create()
创建一个新对象,使用现有的对象来提供新创建的对象的proto。
let o;
// 创建一个原型为null的空对象
o = Object.create(null);
o = {};
// 以字面量方式创建的空对象就相当于:
o = Object.create(Object.prototype);
o = Object.create(Object.prototype, {
// foo会成为所创建对象的数据属性
foo: {
writable: true,
configurable: true,
value: "hello",
},
// bar会成为所创建对象的访问器属性
bar: {
configurable: false,
get() {
return 10;
},
set(value) {
console.log("Setting `o.bar` to", value);
},
},
});
// {foo: 'hello'}
Object.keys()
返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致。
const obj = { name: "javascript", age: 20 };
Object.prototype.history = "lang";
Object.keys(obj); // ['name', 'age']
Object.keys(["a", "b", "c"]); // ['0', '1', '2']
Object.keys({ 100: "a", 2: "b", 7: "c" }); // ['2', '7', '100']
Object.keys("foo"); // ['0', '1', '2']
Object.values()
返回一个给定对象自身的所有可枚举属性值的数组,值的顺序与使用for...in循环的顺序相同(区别在于 for...in 循环枚举原型链中的属性)。
const obj = { name: "javascript", age: 20 };
Object.prototype.history = "lang";
Object.values(obj); // ['javascript', 20]
Object.values({ 100: "a", 2: "b", 7: "c" }); // ['b', 'c', 'a']
Object.entries()
返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for...in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性)。
const obj = { name: "javascript", age: 20 };
Object.prototype.history = "lang";
Object.entries(obj); // [['name', 'javascript'],['age', 20]]
// 对象转Map
new Map(Object.entries(obj)); // Map(2) {'name' => 'javascript', 'age' => 20}
Object.is()
判断两个值是否为同一个值。
Object.is("foo", "foo"); // true
Object.is(window, window); // true
Object.is("foo", "bar"); // false
Object.is([], []); // false
const foo = { a: 1 };
const bar = { a: 1 };
Object.is(foo, foo); // true
Object.is(foo, bar); // false
Object.is(null, null); // true
// 特例
Object.is(0, -0); // false
Object.is(0, +0); // true
Object.is(-0, -0); // true
Object.is(Number.NaN, 0 / 0); // true
Object.getOwnPropertyNames()
返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。
Object.getOwnPropertyNames(["a", "b", "c"]).sort(); // ["0", "1", "2", "length"]
// 类数组对象
const obj = { 0: "a", 1: "b", 2: "c" };
Object.getOwnPropertyNames(obj).sort(); // ["0", "1", "2"]
// 使用Array.forEach输出属性名和属性值
Object.getOwnPropertyNames(obj).forEach((val, idx, array) => {
console.log(val + " -> " + obj[val]);
});
// 输出
// 0 -> a
// 1 -> b
// 2 -> c
// 不可枚举属性
const my_obj = Object.create(
{},
{
getFoo: {
value() {
return this.foo;
},
enumerable: false,
},
},
);
my_obj.foo = 1;
console.log(Object.getOwnPropertyNames(my_obj).sort()); // ["foo", "getFoo"]
Object.getOwnPropertySymbols()
返回一个给定对象自身的所有 Symbol 属性的数组。
let obj = {};
const a = Symbol("a");
const b = Symbol.for("b");
obj[a] = "localSymbol";
obj[b] = "globalSymbol";
const objectSymbols = Object.getOwnPropertySymbols(obj);
console.log(objectSymbols.length); // 2
console.log(objectSymbols); // [Symbol(a), Symbol(b)]
console.log(objectSymbols[0]); // Symbol(a)
// 拓展
// 静态方法 Reflect.ownKeys() 返回一个由目标对象自身的属性键组成的数组。
obj = { name: "javascript", age: 20 };
Object.defineProperties(obj, {
history: {
value: "lang",
},
foo: {
value: Symbol("foo"),
},
});
obj; // {name: 'javascript', age: 20, history: 'lang', foo: Symbol(foo)}
Reflect.ownKeys(obj); // ['name', 'age', 'history', 'foo']
// 等价于
Object.getOwnPropertyNames(obj).concat(Object.getOwnPropertySymbols(obj));
// ['name', 'age', 'history', 'foo']
数据类型 Object - MDN、 内置对象 Reflect - MDN、 比较 Reflect 和 Object 方法 - MDN
for…in 和 for…of
for...in
以任意顺序遍历一个对象的除Symbol以外的可枚举属性,包括继承的可枚举属性。
const obj = { name: "javascript", age: 20 };
Object.prototype.history = "lang";
for (const i in obj) {
console.log(i, obj.hasOwnProperty(i));
}
// name true
// age true
// history false
for...of
- 可迭代对象(包括 Array,Map,Set,String,TypedArray,arguments 对象等等)上创建一个迭代循环;
- 语句可以使用 hasOwnProperty() 加一层过滤以达到 Object.keys() 的效果。
数值数组去重
Set() 的成员值都是唯一的,可以过滤重复的 Number、String、Boolean、undefined、null、NaN, 无法过滤重复的 Object。const arr = [1, 2, 5, 3, 3, 1, 4, 9, 7, 1, 5];
console.log([
...new Set([
1,
1,
"3",
"3",
Number.NaN,
Number.NaN,
undefined,
undefined,
null,
null,
true,
true,
{},
{},
]),
]);
// [1, "3", NaN, undefined, null, true, {}, {}]
通过 Set() 和 扩展运算符
[...new Set(arr)];
// [1, 2, 5, 3, 4, 9, 7]
通过 Array.from()
Array.from(new Set(arr));
// [1, 2, 5, 3, 4, 9, 7]
// 拓展:
[
...new Set([
1,
1,
"3",
"3",
Number.NaN,
Number.NaN,
undefined,
undefined,
null,
null,
true,
true,
{},
{},
]),
];
// [1, "3", NaN, undefined, null, true, {}, {}]
通过 Array.prototype.filter() 和 Array.prototype.indexOf()
function unique(_arr) {
return _arr.filter((item, index, array) => array.indexOf(item) === index);
}
unique(arr); // [1, 2, 5, 3, 4, 9, 7]
通过 Array.prototype.reduce() 和 Array.prototype.includes()
function unique(_arr) {
return _arr.reduce((result, item) => {
return result.includes(item) ? result : [...result, item];
}, []);
}
unique(arr); // [1, 2, 5, 3, 4, 9, 7]
对象数组去重
const objArr = [
{ id: 1, name: "小米" },
{ id: 2, name: "小米2" },
{ id: 5, name: "小东" },
{ id: 2, name: "小米2" },
{ id: 1, name: "小米" },
{ id: 8, name: "小红" },
{ id: 10, name: "小西" },
{ id: 12, name: "小明" },
{ id: 8, name: "小红" },
];
通过 Array.prototype.reduce()
Array.prototype.uniqueArr = function (key) {
if (!Array.isArray(this)) return;
const temp = {};
return this.reduce((result, next) => {
temp[next[key]] ? "" : (temp[next[key]] = true) && result.push(next);
return result;
}, []);
};
objArr.uniqueArr("id");
通过 Array.prototype.filter() 和 Set()/Map()
Array.prototype.uniqueArr = function (key) {
if (!Array.isArray(this)) return;
const set = new Set();
return this.filter((item) => {
return !set.has(item[key]) && set.add(item[key]);
});
// let map = new Map();
// return this.filter(item=>{
// return !map.has(item[key]) && map.set(item[key], 1);
// })
};
objArr.uniqueArr("id");
数组扁平化
Array.prototype.join() 和 Array.prototype.toString() 都可以将多维数组转成普通字符串。const arr = [1, [2, 3], [4, 5]];
arr.join(); // '1,2,3,4,5'
arr.toString(); // '1,2,3,4,5'
通过 Array.prototype.concat() 和 扩展运算符
const arr = [1, [2, 3], [4, 5]];
[].concat(...arr);
// [1, 2, 3, 4, 5]
通过 Array.prototype.join()/Array.prototype.toString() 和 String.prototype.split()
const arr = [1, [2, 3], [4, 5], [6, [7, 8, [9, 10]]]];
arr.join().split(",").map(Number);
arr.toString().split(",").map(Number);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
通过 Array.prototype.flat()
const arr = [1, [2, 3], [4, 5], [6, [7, 8, [9, 10]]]];
arr.flat(); // [1, 2, 3, 4, 5, 6, [7, 8, [9, 10]]]
arr.flat(2); // [1, 2, 3, 4, 5, 6, 7, 8, [9, 10]]
arr.flat(Infinity); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
通过 Array.prototype.reduce()
const arr = [1, [2, 3], [4, 5], [6, [7, 8, [9, 10]]]];
function flatten(_arr) {
return _arr.reduce((result, item) => {
return result.concat(Array.isArray(item) ? flatten(item) : item);
}, []);
}
flatten(arr); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]