文章目录
-
- parseInt
- 手写一个js函数,实现数组扁平化ArrayFlatten
- 手写一个getType函数,获取详细的数据类型
- new一个对象的过程是什么,手写代码表示
- Object.create和{}有什么区别
- 深度优先遍历一个DOM树
- 广度优先遍历一个DOM树
- 深度优先遍历可以不用递归吗
- 手写一个LazyMan,实现sleep机制
- 手写curry函数,实现函数柯里化
- * instanceof原理是什么,请写代码表示
- 手写函数bind功能
- 手写函数call和apply功能
- 手写EventBus自定义事件-包括on和once
- 手写EventBus自定义事件-on和once分开存储
- 用JS实现一个LRU缓存-分析数据结构特点,使用Map
- 不用Map实现LRU缓存-分析问题,使用双向链
- 手写JS深拷贝-考虑各种数据类型和循环引用
parseInt
parseInt默认采用十进制,以0x开头的默认为十六进制
['1', '2', '3'].map(parseInt) 相当于
['1', '2', '3'].map((item, index) => parseInt(item, index)) // 输出[1, NaN, NaN]
['1', '2', '3'].map(item => parseInt(item)) // 输出 [1, 2, 3]
手写一个js函数,实现数组扁平化ArrayFlatten
// 一层扁平化
function arrayFlat(arr) {
const flatArr = []
arr.forEach(item => {
if (Array.isArray(item)) {
item.forEach(v => {
flatArr.push(v) })
} else {
flatArr.push(item)
}
})
return flatArr
}
const arr = [1, [2, [3]], null, {
11: 12 }]
const a = arrayFlat(arr)
// [1, 2, Array(1), null, {…}]
// 深度扁平化
function arrayFlat(arr) {
const flatArr = []
arr.forEach(item => {
if(Array.isArray(item)) {
const flatItem = arrayFlat(item)
flatItem.forEach(v => flatArr.push(v))
// flatArr = flatArr.concat(flatItem)
} else {
flatArr.push(item)
// flatArr = flatArr.concat(item)
}
})
return flatArr
}
// 自己写的方法1
const flatArr = []
function arrayFlat(arr) {
arr.forEach(item => {
if(Array.isArray(item)) {
arrayFlat(item)
} else {
flatArr.push(item)
}
})
}
// 自己写的方法2
function ArrayFlatten(data, flatArr = []) {
data.forEach(item => {
if (Array.isArray(item)) {
return ArrayFlatten(item, flatArr)
} else {
flatArr.push(item)
}
})
return flatArr
}
const arr = [[1, 2, 3], [[4, 5, 6]], ['arr'], null]
arrayFlat(arr)
// [1, 2, 3, null, {…}]
手写一个getType函数,获取详细的数据类型
// 使用 Object.prototype.toString.call(x)
// 注意,不能直接调用 x.toString()
function getType(filed) {
const originType = Object.prototype.toString.call(filed) // [Object String]
const spaceIndex = originType.indexOf(' ')
const type = originType.slice(spaceIndex + 1, -1) // String
return type.toLowerCase()
}
// 自己写的 - 枚举踩雷
// 你可能忽略某些类型
// 增加了新类型,需要修改代码
function getType(filed) {
const type = undefined
if (typeof filed === 'number') {
type = 'number'
} else if (typeof filed === 'string') {
type = 'string'
} else if (typeof filed === 'symbol') {
type = 'symbol'
} else if (typeof filed === 'boolean') {
type = 'boolean'
} else if (typeof filed === 'function') {
type = 'function'
} else if (typeof filed === 'object') {
if (filed = null) {
type = 'null'
} else if (filed instanceof Object) {
type = 'object'
} else if (filed instanceof Array) {
type = 'array'
} else if (filed instanceof Map) {
type = 'map'
}
}
return type
}
new一个对象的过程是什么,手写代码表示
class是function的语法糖
// function形式
function Foo(name, age) {
this.name = name
this.age = age
}
Foo.prototype.getName = function () {
return this.name }
// class 形式
class Foo {
name = ''
age = null
constructor(name, age) {
this.name = name
this.age = age
}
getName() {
return this.name }
}
const f = new Foo('小明', 22)
const name = f.getName()
console.log(name, 'name') // 小明 name
- 创建一个空对象 obj,继承构造函数的原型
- 执行构造函数(将 obj 作为 this)
- 返回obj
function customNew<T>(constructor: Function, ...args: any[]): T {
// 创建一个空对象,继承constructor的原型
const obj = Object.create(constructor.prototype)
// 将obj作为this,执行constructor,传入参数
constructor.apply(obj, args)
// 返回obj
return obj
}
// const f = new Foo('小明')
const f = customNew<Foo>(Foo, '小明')
chatGPT
- 创建一个新对象,其原型指向构造函数的原型
- 使用apply方法调用构造函数,并将新创建的对象作为this上下文
- 检查构造函数的返回值
Object.create和{}有什么区别
- {}创建空对象,原型指向 Object.prototype
- Object.create 创建空对象,原型指向传入的参数
const obj1 = {
}
obj1.__proto__ === Object.protoTYpe
const obj2 = Object.create({
x