1.柯里化
function argsSum(args) {
return args.reduce((pre, cur) => {
return pre + cur
})
}
function add(...args1) {
let sum1 = argsSum(args1)
let fn = function (...args2) {
let sum2 = argsSum(args2)
return add(sum1 + sum2)
}
fn.toString = function () {
return sum1
}
return fn
}
2.手写 instanceof
思路:a 沿着原型链找到 b.prototype,则 a instanceof b = true
,遍历 a 的原型链,找到 b.prototype,返回 true,否则返回 false
const my_instanceof = (A, B) => {
let p = A //指针指向a
while (p) {
//遍历原型链
if (p === B.prototype) {
return true
}
p = p.__proto__
}
return false
}
3.深克隆
function clone(data) {
if (typeof data === 'symbol') {
//symbol,symbol是非object的基本类型
return Symbol().for(data.description)
} else if (typeof data != 'object') {
//基本类型
return data
} else if (data instanceof Array) {
// Array
return data.map(i => clone(i))
} else if (data.constructor === Object) {
//避免 new Date,处理json
let res = {}
for (let key in data) {
res[key] = clone(data[key])
}
return res
} else {
//系统对象及自定义对象 类似于class
return new data.constructor(data)
}
}
4.手写bind
function _bind(asThis) {
var fn = this //记录this
var args = slice.call(arguments, 1)
if (typeof fn != 'function') {
throw new Error('bind需使用在函数上')
}
function resFn() {
var args2 = slice.call(arguments, 0)
return fn.apply(
resFn.prototype.isPrototypeOf(this) ? this : asThis,
args.concat(args2))
}
resFn.prototype = fn.prototype
return resFn
}
5.手写new
function new_operator(_constructor, ...args) {
// ① 创建新对象obj,并关联obj原型到构造函数原型对象上
let obj = Object.create(_constructor.prototype)
// ② 执行构造函数,且绑定this到新对象Obj上,实现继承。同时接受返回值res
let res = _constructor.apply(obj, args)
// ③ 返回值判断
return res instanceof Object ? res : obj
}
6.手写Promise.race
Promise.myRace = arr => {
return new Promise((resolve, reject) => {
arr.forEach(p => p.then(resolve, reject))
})
}
//Promise.any(谁先成功)比Promise.race(谁先完成)好用
7.手写Promise.all
Promise.myall = promises => {
let complete = 0
let result = []
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(res => {
complete++
result[i]= res
if (complete == promises.length) {
resolve(result)
}
}, reject)
}
})
}
8.(京东快手)两数之和
示例:nums = [2,7,11,15] target = 9 //输出[0,1]
思路:nums 去相亲者,target 匹配的条件,字典建立一个介绍所储存相亲者的数字和下标
//obj解法
let nums = [2, 7, 11, 15],
target = 9;
function Two(nums, target) {
const obj = {}
for (let i = 0; i < nums.length; i++) {
let a = nums[i]
let b = target - a
if (obj[b] != undefined) {
return [obj[b], i]
} else {
obj[a] = i
}
}
return null
}
//时间复杂度和空间复杂度都是O(n)
//Map解法
var twoSum = function (nums, target) {
let map = new Map()
for (let i = 0; i < nums.length; i++) {
const n = nums[i]
const n2 = target - n // 符合匹配条件的选手
if (map.has(n2)) {
return [map.get(n2), i] // 返回符合条件对象的下标,自身下标
} else {
map.set(n, i)
}
}
}
//时间复杂度 O(n)//空间复杂度 O(n)//线性
9. 两个数组的交集 题号 349
Map 解题思路,新建立一个字典,遍历 nums1,填充字典,遍历 nums2,遇到字典值就选出,并从字典里删除
var intersection = function (nums1, nums2) {
const map = new Map()
nums1.forEach(n => {
map.set(n, true) //代表这个值在字典里存在
})
let res = []
nums2.forEach(n => {
if (map.get(n)) {
res.push(n)
map.delete(n)
}
})
return res
}
//时间复杂度O(n+m)
//空间复杂度指临时变量内存消耗 O(m)
10.拍平数组,去除重复部分,得到升序不重复数组,[[1,2,2],[3,4,5,5],[6,7,8,9[11,12,[12,13,[14]]]],10]
flat1(arr5)
function flat1(a) {
let res = []
let json = {}
//拍平并去重
for (let i = 0; i < a.length; i++) {
if (typeof a[i] == 'number') {
// if(!res.includes(a[i])){//低性能版
// res.push(a[i])
// }
if (!json[a[i]]) {
//高性能
res.push(a[i])
json[a[i]] = true
}
} else {
flat1(a[i])
}
}
}
11.爬楼梯 70 dp问题
定义子问题f(n) = f(n-1) + f(n-2)
反复执行 从2循环到n,执行上述公式
var clibStairs2 = function (n) {
if (n < 2) {
return 1
}
let dp0 = 1
let dp1 = 1
for (let i = 2; i < n; i++) {
const tmp = dp0
dp0 = dp1
dp1 = dp1 + tmp
}
return dp1
}
//时间复杂度 o(n)
//空间复杂度 o(n)
12.变态版青蛙跳台阶 dp问题
function jump(n){
if(n<0){
return -1
}else if(n==1){
return 1
}else{
return 2*jump(n-1)
}
}
13. 环形链表,题号 141
解题思路:有一快一慢两个指针遍历链表,指针可以相逢,说明有环,返回 true,两个指针不相逢就说明没有环,返回 false
var hasCycle = function (head) {
let p1 = head //慢指针
let p2 = head //快指针
while (p1 && p2 && p2.next) {
p1 = p1.next //走一步
p2 = p2.next.next //走两步
if (p1 === p2) {
//两个指针是否重逢
return true
}
}
return false
}
//有while循环,时间复杂度 O(n)
//空间复杂度:O(1)。因无线性增长结构,矩阵,列表
14.旋转数组 189
function shift(arr, k) {
k %= arr.length
if (k >= Math.floor(arr.length / 2)) {
arr.push(...arr.splice(0, arr.length - k))
} else {
arr.unshift(...arr.splice(arr.length - k, k))
}
return arr
}
15.实现 sleep 函数,等待 1000ms,可以从 promise、generator、async 角度实现,本意问实现 promise
function sleep(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms)
})
}
;(async () => {
console.log(11)
await sleep(2000)
console.log(22)
})()