面试题中手写代码的题目
程序员文章站
2022-06-09 18:45:08
...
数组去重
方法一
export function uniqueArray(arr: any[]) {
return arr.filter((item, index) => arr.indexOf(item) === index)
}
console.log(uniqueArray([1, 2, 3, 2, 1, 3, 4, 5, 6, 3, 8]))
// [1, 2, 3, 4, 5, 6, 8]
方法二
export function uniqueArray(arr: any[]) {
const newArr = arr.sort()
let result = [newArr[0]]
for (let i = 1; i < newArr.length; i++) {
newArr[i] !== newArr[i - 1] && result.push(newArr[i])
}
return result
}
console.log(uniqueArray([1, 2, 3, 2, 1, 3, 4, 5, 6, 3, 8]))
// [1, 2, 3, 4, 5, 6, 8]
js深拷贝
export function deepClone (obj: Object | any) {
let result: any = {}
for (let k in obj) {
let typeStr = Object.prototype.toString.call(obj[k])
.match(/\[object (.*?)\]/)[1].toLowerCase();
switch (typeStr) {
case 'object':
result[k] = deepClone(obj[k])
break
case 'array':
result[k] = obj[k].slice()
break
default:
result[k] = obj[k]
}
}
return result
}
实现一个 instanceof
instanceof 的原理就是判断这个变量是否来自于某一个构造函数
在这里插入代码片export function selfInstanceOf (left, right) {
while (true) {
if (left === null) return false
if (left === right) return true
if (left.__proto__ === right.prototype) return true
left = left.__proto__
}
}
// test
selfInstanceOf({}, Object) // true
selfInstanceOf({}, Array) // false
selfInstanceOf([], Array) // true
selfInstanceOf([], Object) // true
const Fn = function() {}
const a = new Fn()
selfInstanceOf(a, Fn) // true
selfInstanceOf(a, Object) // true
手写 Object.create 方法
科里化函数
通过判断参数是否符合实际方法所需参数的数量进行执行函数或者继续递归判断
export function curry (fn: Function) {
const _this = this
const args = Array.from(arguments).slice(1)
// fn.length 属性指明函数的形参个数。
const len = fn.length
return function () {
const _args = Array.from(arguments)
args.push(..._args)
if (args.length < len) {
return curry.call(_this, fn, ...args)
}
return fn.apply(_this, args)
}
}
// test
const addCur = function (a, b, c) {
console.log('a + b + c', a + b + c)
}
const reduceCur = function (a, b, c) {
console.log('a - b - c', a - b - c)
}
const add = curry(addCur, 2)
s(1)(2) // a + b + c 6
s(1, 3) // a + b + c 6
const reduce = curry(reduceCur)
reduce(1)(2)(3) // a - b - c -1
reduce(1, 2, 3) // a - b - c -3
compose
类似react中组件, compose(fn1, fn2, fn3) (…args) = > fn1(fn2(fn3(…args)))
export function compose (...fn: Function[]) {
return function (...args: any) {
return fn.reduceRight((prevResult, currentFn) => {
return currentFn.call(this, ...prevResult)
}, args)
}
}
实现一个 instanceof
instanceof 的原理就是判断这个变量是否来自于某一个构造函数
export function selfInstanceOf (left, right) {
while (true) {
if (left === null) return false
if (left === right) return true
if (left.__proto__ === right.prototype) return true
left = left.__proto__
}
}
// test
selfInstanceOf({}, Object) // true
selfInstanceOf({}, Array) // false
selfInstanceOf([], Array) // true
selfInstanceOf([], Object) // true
const Fn = function() {}
const a = new Fn()
selfInstanceOf(a, Fn) // true
selfInstanceOf(a, Object) // true
手写bind
注意:bind方法只是返回一个可执行函数,执行需要由用户自己执行返回的函数
Function.prototype.selfBind = function (context: Window = window) {
const fn = this
const ctx = context || {}
const arg = Array.from(arguments).slice(1)
return function () {
fn.call(ctx, ...arg)
}
}
foo.getA.selfBind(null, 'selfBind', 22)()
// prop: undefined
// name: selfBind
// age: 22
// -------------------
手写apply
apply同样也是返回一个执行结果,只是第二个参数为数组
Function.prototype.selfApply = function (context: Window = window) {
const ctx = context || {}
ctx.fn = this
const arg = Array.from(arguments).slice(1)[0]
const result = ctx.fn(...arg)
delete ctx.fn
return result
}
// 接着call的对象信息执行代码
foo.getA.selfApply(bar, ['selfApply', 22])
// prop: this is bar
// name: selfApply
// age: 22
// -------------------
手写call
call返回一个执行结果,第二个及以后的参数为执行函数的参数
Function.prototype.selfCall = function (context: Window = window) {
const ctx = context || {}
ctx.fn = this
const args = Array.from(arguments).slice(1)
const result = ctx.fn(args)
delete ctx.fn
return result
}
const bar = {
a: 'this is bar'
}
const foo = {
a: 1,
getA: function (name, age = 0) {
console.log(`prop: ${this.a}`)
console.log(`name: ${name}`)
console.log(`age: ${age}`)
console.log('-------------------')
}
}
foo.getA.selfCall(bar, 'selfCall')
// prop: this is bar
// name: selfCall
// age: 0
// -------------------
JS节流函数
节流的概念为多次点击的过程中只会在每次大于wait等待时长执行方法
export function throttle (fn: Function, wait: number = 1000) {
let prev: number = +new Date()
return function () {
const now: number = +new Date
if (now - prev > wait) {
fn.apply(this, arguments)
prev = +new Date()
}
}
}
JS防抖函数
基本的防抖函数
export function debounce (fn: Function, wait: number = 1000) {
let t: any
return function () {
const _this = this
t && clearTimeout(t)
t = setTimeout(function() {
fn.apply(_this, arguments)
}, wait)
}
}
添加 immediate 参数
export function debounce (fn: Function, wait: number = 1000, immediate: boolean = true) {
let t: any
return function () {
const _this = this
const _arg = arguments
t && clearTimeout(t)
if (immediate) {
let isDo = !t
t = setTimeout(function() {
t = null
}, wait)
if (isDo) {
fn.apply(_this, _arg)
}
} else {
t = setTimeout(function() {
fn.apply(_this, _arg)
}, wait)
}
}
}
上一篇: 利用别人的程序再次入侵
下一篇: 7-2 交换最小值和最大值 (15分)