<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 手写实现Array.prototype.map
function map(arr, mapCallback) {
// 首先检查传递的参数是否正确
if (!Array.isArray(arr) || !arr.length || typeof mapCallback !== 'function') {
return []
} else {
// 每次调用此函数时,我们都会创建一个 result 数组
// 因为我们不想改变原始数组。
let result = []
for (let i = 0; i < arr.length; i++) {
result.push(mapCallback(arr[i], i, arr))
}
return result
}
}
// 手动实现Array.prototype.filter
function filter(arr, filterCallback) {
if (!Array.isArray(arr) || !arr.length || typeof mapCallback !== 'function') {
return []
} else {
// 每次调用此函数时,我们都会创建一个 result 数组
// 因为我们不想改变原始数组。
let result = []
for (let i = 0; i < arr.length; i++) {
// 检查 filterCallback 的返回值是否是真值
if (filterCallback(arr[i], i, arr)) {
// 如果条件为真,则将数组元素 push 到 result 中
result.push(arr[i])
}
}
return result
}
}
// 手写实现reduce
function reduce(arr, reduceCallback, initialValue) {
if (!Array.isArray(arr) || !arr.length || typeof reduceCallback !== 'function') {
return []
} else {
// 如果没有将initialValue传递给该函数,我们将使用第一个数组项作为initialValue
let hasInitialValue = initialValue !== undefined
let value = hasInitialValue ? initialValue : arr[0]
// 如果有传递 initialValue,则索引从 1 开始,否则从 0 开始
for (let i = hasInitialValue ? 0 : 1; i < arr.length; i++) {
value = reduceCallback(value, arr[i], i, arr)
}
return value
}
}
// 深拷贝
function deepCopy(newObj, oldObj) {
for (let k in oldObj) {
var item = oldObj[k]
// 判断数组
if (item instanceof Array) {
newObj[k] = []
deepCopy(newObj[k], item)
// 判断对象
} else if (item instanceof Object) {
newObj[k] = {}
deepCopy(newObj[k], item)
} else {
newObj[k] = item
}
}
}
// 手写实现call
Function.prototype.myCall = function (context) {
// 判断调用对象
if (typeof this !== 'function') {
console.error('type error')
}
// 获取参数
let args = [...arguments].slice(1)
result = null
// 判断context是否传入,如果为传入,设置成window
context = context || window
// 将调用函数设置成对象的方法
context.fn = this
// 调用函数
result = context.fn(...args)
// 将属性删除
delete context.fn
return result
}
// 手写实现apply
Function.prototype.myApply = function (context) {
if (typeof this !== 'function') {
console.error('type error')
}
context = context || window
let result = null
context.fn = this
// 调用方法
if (arguments[1]) {
result = context.fn(...arguments[1])
} else {
result = context.fn()
}
delete context.fn
return result
}
// 手写实现bind
Function.prototype.myBind = function (context) {
// 判断调用对象是否为函数
if (typeof this !== "function") {
throw new TypeError("Error");
}
// 获取参数
var args = [...arguments].slice(1)
fn = this
return function Fn() {
// 根据调用方式,返回不同的值
return fn.apply(this instanceof Fn ? this : context, args.concat(...arguments))
}
}
// 函数柯理化
// 是一种将使用多个参数的一个函数转换成一系列使用一个参数的函数的技术。
function curry(fn, args) {
let length = fn.length
args = args || []
return function () {
let subArgs = args.slice(0)
// 拼接得到的所有参数
for (let i = 0; i < arguments.length; i++) {
subArgs.push(arguments[i])
}
// 判断参数长度是否满足函数所需参数的长度
if (subArgs.length >= length) {
// 执行函数
return fn.apply(this, subArgs)
} else {
return curry.call(this, fn, subArgs)
}
}
}
// ES6实现
function curry(fn, args) {
return fn.length <= args.length ? fn(...args) : curry.bind(null, fn, ...args)
}
// 快速排序
function quickSort(arr) {
if (arr.length <= 1) {
return arr
}
const cIndex = Math.floor(arr.length / 2)
const index = arr.splice(cIndex, 1)
var l = []
var r = []
for (var i = 0; i < arr.length; i++) {
if (arr[i] < index) {
l.push(arr[i])
} else {
r.push(arr[i])
}
}
return quickSort(l).concat(index, quickSort(r))
}
console.log(quickSort([1, 8, 4, 6, 5, 9, 2, 3, 15, 45])); // (10) [1, 2, 3, 4, 5, 6, 8, 9, 15, 45]
// 冒泡排序
function mySort(arr) {
if (arr == null || arr.length <= 1) {
return arr
}
for (var i = 0; i < arr.length - 1; i++) {
var done = true
for (var j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
var temp = arr[j]
arr[j] = arr[j + 1]
arr[j + 1] = temp
done = false
}
}
if (done) {
break
}
}
return arr
}
alert(mySort([1, 5, 4, 6, 8, 3, 2]))
// 深拷贝
function deepClone(newObj, oldObj) {
for (let k in oldObj) {
let item = oldObj[k]
}
if (item instanceof Array) {
newObj[k] = []
deepClone(newObj[k], item)
} else if (item instanceof Object) {
newObj[k] = {}
deepClone(newObj[k], item)
} else {
newObj[k] === item
}
}
// 手写Promise
function myPromise(constructor) {
let self = this;
self.status = 'Pending'
self.value = undefined
self.reason = undefined
function resolve(value) {
if (self.status === 'Pending') {
self.value = value
self.status = 'resolved'
}
}
function reject(reason) {
if (self.status === 'Pending') {
self.reason = reason
self.status = 'rejected'
}
}
try {
constructor(resolve, reject)
} catch (e) {
reject(e)
}
}
myPromise.prototype.then = function (onFulfilled, onRejected) {
let self = this
switch (self.status) {
case 'resolved':
onFulfilled(self.value)
break
case 'rejected':
onRejected(self.reason)
break
default:
}
}
// instanceof 原理
function myInstanceof(left, right) {
let prototype = right.prototype
left = left.__proto__
while (true) {
if (left === null || left === undefined)
return false
if (prototype === left)
return true
left = left.__proto__
}
}
// 函数节流
function throttle(fn, delay) {
var preTime = Data.now()
return function () {
var context = this
args = arguments
nowTime = Data.now()
if (nowTime - preTime > delay) {
preTime = Data.now()
return fn.apply(context, args)
}
}
}
// 函数防抖
function debounce(fn, wait) {
var timer = null
return function () {
var context = this
args = arguments
if (timer) {
clearTimeout(timer)
timer = null
}
timer = setTimeout(() => {
fn.apply(context, args)
}, wait)
}
}
</script>
</body>
</html>
几道常考的手写面试题
最新推荐文章于 2023-02-13 10:15:07 发布