1.reduce方法
<script>
// Math.pow(m,n)->m^n就是求m的n次方方法是Math.pow
// [].reduce((pre,cur,index,array)=>{
// pre上一次的值,cur当前循环的值,index是当前索引值,array当前数组,c是初始化值,传的化就是pre为c不传,就是pre为array[0]的值
// },c)
[3, 2, 1].reduce(Math.pow)//9求Math.pow的求平方的
[3].reduce(Math.pow)//3-Math.pow不执行,callback不执行
// [].reduce(Math.pow, 3)//3 Math.pow不执行,callback不执行
// [].reduce(Math.pow)//undefined . error
</script>
2.js求素数
// js求素数
function isDel(n) {
if (n == 1) {
return false
}
if (n == 2) { return true }
for (let i = 2; i < n; i++) {
if (n % i === 0) {
return false
}
}
return true
}
// 1-100
const result = []
for (let j = 1; j <= 100; j++) {
if (isDel(j)) {
result.push(j)
}
}
// 求平方根Math.sqrt(n)求平方根就是n的平方根
console.log(result)
3.fill数组填充
// fill数组填充的坑
Array.from({ length: 3 }).fill(0)// [0, 0, 0]
const c = [1, 2, 3]
Array.from({ length: 3 }).fill(c)//[Array(3), Array(3), Array(3)]
c[1] = 'dai'
Array.from({ length: 3 }).fill(c)
// 用双层for循环来构造二维数组
let arr = []
for (let i = 0; i < 3; i++) {
const tem = []
for (let j = 0; j < 3; j++) {
// tem[0]=0,tem[1]=0,tem[2]=0
tem[j] = 0
}
// arr[0]=[tem],
arr[i] = tem
// 修改arr第一个索引数组的第一个值
arr[0][0] = 1
console.log(arr)
}
4.逻辑运算符
// 运算符
let a = 0
let b = 1
let c = b.value?.v
a ||= 10
b &&= 2
c ??= 5
console.log(a)//10
console.log(b)//2
console.log(c)
console.log(a + b + c)//17
console.log(11 ?? 1)//11
// 双问号运算符只判断null和undefined
5数组中找到与目标值最接近的数字
const arr = [1, 3, 5, 6, 10]
// 方法1
function getClosestNumber(array, target) {
let result = array[0]
for (let i = 0; i < array.length; i++) {
if (Math.abs(array[i] - target) < Math.abs(result - target)) {
result = array[i]
}
}
return result
}
// 方法2
function getClosestNumber(array, target) {
return array.reduce((pre, cur) => {
return Math.abs(pre - target) < Math.abs(cur - target) ? pre : cur
})
}
const res1 = getClosestNumber(arr, 7)//6
const res2 = getClosestNumber(arr, 3)//3
console.log('res1:', res1)
console.log('res2:', res2)const arr = [1, 3, 5, 6, 10]
// 方法1
function getClosestNumber(array, target) {
let result = array[0]
for (let i = 0; i < array.length; i++) {
if (Math.abs(array[i] - target) < Math.abs(result - target)) {
result = array[i]
}
}
return result
}
// 方法2
function getClosestNumber(array, target) {
return array.reduce((pre, cur) => {
return Math.abs(pre - target) < Math.abs(cur - target) ? pre : cur
})
}
const res1 = getClosestNumber(arr, 7)//6
const res2 = getClosestNumber(arr, 3)//3
console.log('res1:', res1)
console.log('res2:', res2)
6. 遍历对象的方式
// 遍历对象的方式有5种for in Object.keys() Object.getOwnPropertyNames() Object.getOwnPropertySymbols() Reflect.ownKeys()
// 原型属性
const obj = Object.create({ bar: 'bar' })
// 对象可 枚举属性
obj.foo = 'foo'
// 对象不可枚举属性
Object.defineProperty(obj, 'name', {
enumerable: false,
value: 'kex'
})
// Symbol属性
obj[Symbol('age')] = 'age'
for (let key in obj) {
console.log(key, obj[key])//foo foo bar bar
}
Object.keys(obj)//['foo']
// Object.getOwnPropertyNames()获取对象自身的所以属性名,包括不可枚举的属性,不包含原型链上的属性和symbol属性
// Reflect.ownKeys(),所以的对象所有的属性都输出出来
7. 把稀疏数组变成密集数组的方法
// 稀疏数组和密集数组
// 密集数组是数组元素之间紧密相连,稀疏数组数组之间存在间隙
const arr = [1, 2, 3]
const arr1 = [1, 2, 3]
arr1[8] = 8
// arr1
console.log(arr1)//[1, 2, 3, empty × 5, 8]length=9
// 把稀疏数组变成密集数组的方法
const arr4 = new Array(3)//稀疏数组
const arr5 = Array.apply(null, Array(3))//密集数组[undefined,undefined,undefined]
const arr6 = Array.from({ length: 3 }, () => { })//密集数组 [undefined, undefined, undefined]
// 密集数组的1-10的方法
Array.from({ length: 10 }).map((x, i) => i + 1)// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]得到1-10的数组
Array.apply(null, Array(10)).map((x, i) => i + 1)//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]得到1-10的数组
8.数组1到n中1出现的次数
// 整体思想:以字符串形势进行遍历
//方法1: 将数字转换为字符串,使用正则匹配其中出现的1的数量
// 方法2:将数字转换为字符串,再转换为数组,通过filter方法过滤出1的值
// 方法1
function findOne(n) {
return Array.from({ length: n }).map((v, i) => i + 1).reduce((pre, cur) => {
const curCount = String(cur).match(/1/g)?.length || 0
return pre + curCount
}, 0)
}
findOne(10)//2
findOne(20)//12
findOne(2000)
// 方法2
function findOne2(c) {
return Array.from({ length: c }).map((v, i) => i + 1).reduce((pre, cur) => {
const cumt = String(cur).split('').filter((i) => i === '1').length
return pre + cumt
}, 0)
}
findOne2(10)
findOne2(20)
9.设计一个任务队列并控制并发数
// 同时执行任务数为10个
// 释放任务队列空间
// promise的执行函数
function createTask(i) {
return () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(i)
}, 2000)
})
}
}
// 执行的10个任务
class TaskQueue {
constructor() {
this.max = 10
this.taskList = []
setTimeout(() => {
this.run()
})
}
// 添加任务队列
addTask(task) {
this.taskList.push(task)
}
// 自动执行run方法
run() {
const length = this.taskList.length
if (!length) {
return
}
const min = Math.min(this.max, length)
for (let i = 0; i < min; i++) {
this.max--
const task = this.taskList.shift()
task().then(res => {
console.log(res)
}).catch(error => {
console.log(error)
}).finally(() => {
this.max++
this.run()
})
}
}
}
const taskQueue = new TaskQueue()
for (let i = 0; i < 20; i++) {
const task = createTask(i)
taskQueue.addTask(task)
}
10.求出n个连续数组的最大和
// 求n个连续数组的最大和
// 求和函数
function arrSum(arr) {
return arr.reduce((pre, cur) => pre + cur)
}
// 截取数组函数并比较大小
function getMax(arr, n) {
let left = 0
let right = left + n
let max = arrSum(arr.slice(left, right))
for (; right <= arr.length; left++, right++) {
const curSum = arrSum(arr.slice(left, right))
max = Math.max(curSum, max)
}
return max
}
const arr = [2, 5, 3, 4, 6]
const res1 = getMax(arr, 2)//10
const res2 = getMax(arr, 3)//13
console.log(res1)
console.log(res2)
11.考察this指向问题
// 考察this指向问题
// this=函数的调用者
// arguments=函数实际传递的参数
var length = 1
function fn() {
console.log(this.length)
}
var obj = {
length: 100,
action: function (callback) {
// 输出1
callback() //this->window->1
// 输出2,因为有5个参数[fn,1, 2, 3, 4]
arguments[0]()//输出5
// 输出3
var foo = arguments[0]
foo()//this指向的是window输出1
// 输出4
this.foo2 = arguments[0]
this.foo2()//this的指向为obj,obj的length长度为100,所以输出为100
}
}
var arr1 = [1, 2, 3, 4]
obj.action(fn, ...arr1)
// 引题
var length = 1;
function foo() {
console.log(this.length)
};
var arr2 = [foo, 2, 3];
console.log(arr2[0]())
arr2[0]();//foo this->arr2->3
var f1 = arr2[0] // f1前面没有载体,this指向window 结果为1
f1()
12.计算对象的层数(递归运算)
const obj = {
a: 'a',
b: {
c: {
d: 'd',
e: 'e',
}
},
f: {
g: {
h: {
i: 'i',
}
},
}
}
function getLEvel(obj) {
let result1 = 1
function fn(param, level = 0) {
if (typeof param === 'object' && param !== null) {
Object.values(param).forEach(item => {
if (typeof item === 'object' && item !== null) {
fn(item, level + 1)
} else {
result1 = level + 1 > result1 ? level + 1 : result1
}
})
} else {
result1 = level > result1 ? level : result1
}
}
fn(obj)
return result1
}
console.log(getLEvel(obj))
13.函数柯里化
// 函数柯里化
// reduce求和
function argsSum(args) {
return args.reduce((pre, cur) => {
return pre + cur
}, 0);
}
const foo = (...args1) => {
const sum1 = argsSum(args1)
const fu = (...args2) => {
const sum2 = argsSum(args2)
return foo(sum1 + sum2)
}
// 返回一个函数
fu.toString = () => {
return sum1;
}
return fu
}
// foo(1,2,3)==6;
console.log(foo(1, 2, 3) == 6)
console.log(foo(1)(2, 3) == 6)
console.log(foo(1)(2)(4)(3) == 10)