一些js代码

一些js代码

统计数组中元素出现次数

reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。
reducer 函数接收4个参数:

1.Accumulator (acc) (累计器)
2.Current Value (cur) (当前值)
3.Current Index (idx) (当前索引)
4.Source Array (src) (源数组)
您的 reducer 函数的返回值分配给累计器,该返回值在数组的每个迭代中被记住,并最后成为最终的单个结果值。


1
2
3
4
5
const count = arr => arr.reduce((acc, val) => {
acc[val] = (acc[val] || 0) + 1;
return acc;
},{})
count([1,1,2,3,1,1,2]); // {1:4,2:2,3:1}

数组扁平化(完全)

concat() 方法用于连接两个或多个数组。该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。


1
2
3
4
5
6
const aryFlatten = arr => [].concat(...arr.map(v => Array.isArray(v) ? aryFlatten(v) :v))

reduce版
const aryFlatten = arr => arr.reduce((a, v) => a.concat(Array.isArray(v) ? aryFlatten(v) : v),[])

aryFlatten([1, [2], [[3], 4], 5]); // [1,2,3,4,5]

根据提供的层数扁平化

1
2
3

const flattenBy = (arr, depth=1) => arr.reduce((a, v) => a.concat(depth>1 && Array.isArray(v) ? flattenBy(v, depth-1) : v),[])
flattenBy([1, [2, [3, [4, 5], 6], 7], 8], 2); // [1, 2, 3, [4, 5], 6, 7, 8]

去除数组中的所有假植

1
2
3

const filterFalsy = arr => arr.filter(Boolean)
filterFalsy(['', true, {}, false, 'sample', 1, 0]); // [true, {}, 'sample', 1]

获取指定值在数组中出现的所有下标

1
2
3

const indexOfAll = (arr, val) => arr.reduce((a, v, i) => v===val? [...a,i]: a,[])
indexOfAll([1, 2, 3, 1, 2, 3], 1); // [0,3]

通过给定的结束值,开始值,步长生成数组

Array.from() 方法从一个类似数组或可迭代对象中创建一个新的数组实例。
Math.ceil 向上取整


1
2
3
4
5
6
7

const initializeArrayWithRange = (end, start=0, step=1) =>
Array.from({length: Math.ceil(end-start+1)/step}, (v, i)=> i*step+start)

initializeArrayWithRange(5); // [0,1,2,3,4,5]
initializeArrayWithRange(7, 3); // [3,4,5,6,7]
initializeArrayWithRange(9, 0, 2); // [0,2,4,6,8]

获取两个数组的交集

1
2
3
4
5
6
7
8
9

const intersection = (a, b) => {
const s = new Set(b)
return a.filter(x => s.has(x))
}

const intersection = (a, b) => a.filter(x => b.includes(a))

intersection([1, 2, 3], [4, 3, 2]); // [2, 3]

打乱数组顺序

1
2
3
4
5
6
7
8
9
10

const shuffle = arr =>{
let m = arr.length;
while(m){
let i = Math.floor(Math.random() * m--)
[arr[i],arr[m]] = [arr[m],arr[i]]
}
return arr;
}
shuffle([1, 2, 3]); // [2, 3, 1]

根据提供的方法留下符合条件的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

const uniqueElementsBy = (arr, fn) => arr.reduce((acc, val) => {
!acc.some(x => fn(x,val))?acc.push(val):''
return acc;
}
,[])

uniqueElementsBy(
[
{ id: 0, value: 'a' },
{ id: 1, value: 'b' },
{ id: 2, value: 'c' },
{ id: 1, value: 'd' },
{ id: 0, value: 'e' }
],
(a, b) => a.id == b.id
);
返回 [ { id: 0, value: 'a' }, { id: 1, value: 'b' }, { id: 2, value: 'c' } ]

防抖

1
2
3
4
5
6
7
8

const debounce = (fn, ms=0)=>{
let timer;
return fn(...args){
clearTimeout(timer);
timer = setTimeout(() => fn.bind(this,args),ms)
}
}

先立即执行一次再防抖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

const debounce = (fn, ms=0, immediate=true)=>{
let timer;
return function(...args){
if(timer) clearTimeout(timer)
if(immediate){
fn()
immediate=false
}else{
timer = setTimeout(()=>{
fn.apply(this,args)
immediate=true
},ms)
}
}
}

斐波那契

1
2
3
4
5
6
7
8
9
10
11

const fb = (n) => Array.from({length:n+1}).reduce((acc,val,i) =>
(acc.concat(i>1?acc[i-2]+acc[i-1]:i)),[])

fb(5) // [1,1,2,3,5]
只要最后一项

function fb(n){
return n < 2 ? n : fb(n - 1) + fb(n - 2);
}
fb(5) // 5

先立即执行一次再节流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

const throttle = (fn, wait) => {
let inThrottle, lastFn, lastTime;
return function() {
const context = this,
args = arguments;
if (!inThrottle) {
fn.apply(context, args);
lastTime = Date.now();
inThrottle = true;
} else {
clearTimeout(lastFn);
lastFn = setTimeout(function() {
if (Date.now() - lastTime >= wait) {
fn.apply(context, args);
lastTime = Date.now();
}
}, Math.max(wait - (Date.now() - lastTime), 0));
}
};
};

只执行一次的方法

1
2
3
4
5
6
7
8
9

const once = fn => {
let called = false;
return fn(...args){
if(called) return;
called = true;
return fn.apply(this,...args)
}
}

生成指定范围内的n个随机数

1
2
3

const randomIntArrayInRange = (max, min, n) =>
Array.from({length:n},()=> Math.floor(Math.random() * (max-min+1) + min)))

深拷贝

1
2
3
4
5
6
7
8
9
10
11
12

const deepClone = obj => {
let clone = Object.assign({}, obj);
Object.keys(clone).forEach(
key => (clone[key] = typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key])
);
return Array.isArray(obj) && obj.length
? (clone.length = obj.length) && Array.from(clone)
: Array.isArray(obj)
? Array.from(obj)
: clone;
};

计算大整数之和

1
2
3
4
5
6
7
8
9
10
11
function sumStrings(a, b) {
var res = '', c = 0;
a = a.split('');
b = b.split('');
while (a.length || b.length || c) {
c += ~~a.pop() + ~~b.pop();
res = c % 10 + res;
c = c > 9;
}
return res.replace(/^0+/, '');
}

new的模拟实现

1
2
3
4
5
6
7
8
9
10
11
12
13
function objectFactory() {

var obj = new Object(),

Constructor = [].shift.call(arguments);

obj.__proto__ = Constructor.prototype;

var ret = Constructor.apply(obj, arguments);

return typeof ret === 'object' ? ret : obj;

};

继承

构造继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function Parent(){
this.arr = [1,2,3]
this.name = 'parent'
}

function Child(){
Parent.apply(this);
}

Parent.prototype.id = '1'
var child1 = new Child();
console.log(child1.name,child1.id) // parent undefined

总结:构造继承不会继承父级原型上的属性

原型继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

function Parent(){
this.arr = [1,2,3]
this.name = 'parent'
}

function Child(){
this.age = 3
}

Child.prototype = new Parent();
Parent.prototype.id = '1'
let child1 = new Child();
console.log(child1.name,child1.id) // parent 1
child1.arr[0] = 3
child1.name = 'child'
let child2 = new Child();
console.log(child2.arr,child2.name) // [3,2,3],parent

总结:原型继承继承了原型上的属性,但是改变原型上的应用类型,所有实例对象的该属性都会被改变

组合继承

1
2
3
4
5
6
7
8
9
10
11
function Parent(){
this.arr = [1,2,3]
this.name = 'parent'
}

function Child(){
this.age = 3
}

let obj = Object.create(Parent.prototype)
Child.prototype.constructor = Child
# 知识

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×