import { CodeSandbox } from '@/components/CodeSandbox'
手写题
题目 1:防抖和节流实现
总结:
题目 2:new
总结:
- 先创建一个空对象,对象的隐式原型指向构造函数的显示原型,用 Object.create 实现更好
- 然后执行构造函数,将构造函数的 this 指向这个空对象,拿到执行结果
- 最后返回这个空对象,如果构造函数返回的是一个对象,则返回这个对象,否则返回这个空对象
Object.create(Fn.prototype) 和 const obj = {} {}.proto = Fn.prototype 其实没有什么大区别,也就是 Object.create 更遵循 ES6 写法规范,两者输出是是一样的
题目 3:instanceof
总结:
- 核心逻辑是左边的 proto 上一直查找有没有等于右边的 prototype,有就返回 true,没有就返回 false
- while 循环,直到 proto 为 null 为止,因为原型链的尽头是 null,退出条件是找到了则返回 true,没找到则在循环外返回 false
- 在循环中 proto = Object.getPrototypeOf(proto) 一直往上找
题目 4:拍平数组
总结:
题目 5:深拷贝
总结:
题目 6:控制请求并发
总结:
- 递归实现
- 先根据 max 创建 max 个请求,
- 然后定义 runNext 函数
- runNext 核心是两个计数变量,一个记录当前队列的索引 index,一个记录正在执行的请求数 running
- 退出条件是 index >= arr.length 或者 running >= max
- index++ 和 新建一个 const currentIndex = index++ 拿到当前任务的索引来执行
- 最后在 finally 中递归调用 runNext 函数,这时候 running--,实现并发控制
对于 index++ 和 ++index 的区别:
js
let index = 0
const result = index++
console.log(result) // 输出: 0 (返回自增前的值)
console.log(index) // 输出: 1 (变量已自增)
let index = 0
const result = ++index
console.log(result) // 输出: 1 (返回自增后的值)
console.log(index) // 输出: 1 (变量已自增)let index = 0
const result = index++
console.log(result) // 输出: 0 (返回自增前的值)
console.log(index) // 输出: 1 (变量已自增)
let index = 0
const result = ++index
console.log(result) // 输出: 1 (返回自增后的值)
console.log(index) // 输出: 1 (变量已自增)题目 7:数组转树
总结:
题目 8:大文件上传
题目 9:Call
js
Function.prototype.myCall = function (context, ...args) {
context = context || window
const fnKey = Symbol()
context[fnKey] = this
const res = context[fnKey](...args) // 相当于谁调用,this就指向谁
delete context[fnKey]
return res
}
// 测试示例
function greet(greeting, other) {
return `${greeting}, ${this.name}${other}`
}
const person = { name: 'Alice' }
greet.myCall(person, 'Hello', '!') // 输出: Hello, Alice!Function.prototype.myCall = function (context, ...args) {
context = context || window
const fnKey = Symbol()
context[fnKey] = this
const res = context[fnKey](...args) // 相当于谁调用,this就指向谁
delete context[fnKey]
return res
}
// 测试示例
function greet(greeting, other) {
return `${greeting}, ${this.name}${other}`
}
const person = { name: 'Alice' }
greet.myCall(person, 'Hello', '!') // 输出: Hello, Alice!题目 10:Apply
js
Function.prototype.myApply = function (context, argsArray) {
context = context || window
const fnKey = Symbol()
context[fnKey] = this
const args = Array.isArray(argsArray) ? argsArray : []
const res = context[fnKey](...args) // 相当于谁调用,this就指向谁
delete context[fnKey]
return res
}
// 测试示例
function greet(greeting, other) {
return `${greeting}, ${this.name}${other}`
}
const person = { name: 'Alice' }
greet.myApply(person, ['Hello', '!']) // 输出: Hello, Alice!Function.prototype.myApply = function (context, argsArray) {
context = context || window
const fnKey = Symbol()
context[fnKey] = this
const args = Array.isArray(argsArray) ? argsArray : []
const res = context[fnKey](...args) // 相当于谁调用,this就指向谁
delete context[fnKey]
return res
}
// 测试示例
function greet(greeting, other) {
return `${greeting}, ${this.name}${other}`
}
const person = { name: 'Alice' }
greet.myApply(person, ['Hello', '!']) // 输出: Hello, Alice!