JavaScript常见手写题
- 0
#讨论区
00条评论
实时对话
loading...
javascript
javascript
javascript
js
javascript
javascript
javascript
javascript
javascript
javascript
javascript
javascript
创建一个空的简单Javascript对象 (即);
继承父类原型上的方法;
添加父类的属性到新的对象上并初始化. 保存方法的执行结果;
如果执行结果有返回值并且是一个对象, 返回执行的结果, 否则, 返回新创建的对象;
javascript
javascript
javascript
javascript
javascript
定时器版本
javascript
时间戳版本
javascript
javascript
javascript
//reduce实现
Array.prototype.myMap = function (fn) {
return this.reduce((previousValue, currentValue, idx) => {
previousValue.push(fn(currentValue, idx))
return previousValue
}, [])
}
//代码https://github.com/zzfn/best-practice/blob/main/javascript/other/flat.js
//递归
Array.prototype.myFlat = function (level = 1) {
const array = this
if (level > 0) {
let result = [];
for (const item of array) {
if (Array.isArray(item)) {
result = [...result, ...item.myFlat(level - 1)]
} else {
result.push(item)
}
}
return result;
} else {
return array;
}
}
//reduce
Array.prototype.myFlat = function (level = 1) {
return level > 0 ? this.reduce((acc, item) => {
if (Array.isArray(item)) {
return [...acc, ...item.myFlat(level - 1)]
} else {
return [...acc, item]
}
}, []) : this
}
console.log([1, 2, [3, [4, [5]]]].myFlat(2))
const arr = [1, 2, 3, 4, 5];
Array.prototype.myReverse = function () {
const o=[]
const arr=this
while (arr.length){
o.unshift(arr.shift())
}
return o
}
console.log(arr.myReverse())
Array.prototype.myReduce = function (fn, initialValue) {
let acc = initialValue;
for (let i = 0; i < this.length; i++) {
if (acc === undefined) {
acc = this[i];
} else {
acc = fn(acc, this[i], i, this);
}
}
return acc;
}
Array.prototype.myReduce = function (callback, initialValue) {
// 判断调用该API的元素是否为null
if (this == null) {
throw new TypeError('this is null or not defined')
}
// 判断是否为function
if (typeof callback !== "function") {
throw new TypeError(callback + ' is not a function')
}
const arr = this
const len = arr.length
// 第二个参数
let accumulator = initialValue
let index = 0
// 如果第二个参数是undefined 则数组的第一个有效值
// 作为累加器的初始值
if (accumulator === undefined) {
// 找到数组中的第一个有效值 不一定就是arr[0]
while (index < len && !(index in arr)) {
index++
}
if (index >= len) {
throw new TypeError('Reduce of empty array with no initial value')
}
// 输出第一个有效数组元素,作为累加器的第一个元素
accumulator = arr[index++]
}
while (index < len) {
if (index in arr) {
// arr[index] 为 accumulator 的下一个元素
accumulator = callback.call(undefined, accumulator, arr[index], index, arr)
}
// 持续后移
index++
}
// 返回结果
return accumulator
}
Array.prototype.myReduce=function(fn,initalValue){
let initialArr = this;
let arr = initialArr.concat();
if (initalValue) arr.unshift(initalValue);
let index, newValue;
while (arr.length > 1) {
index = initialArr.length - arr.length + 1;
newValue = fn.call(null, arr[0], arr[1], index, initialArr);
arr.splice(0, 2, newValue);
}
return newValue;
}
Array.prototype.myForEach = function (callback, thisArg) {
// 判断调用该API的元素是否为null
if (this == null) {
throw new TypeError('this is null or not defined')
}
// 判断是否为function
if (typeof callback !== "function") {
throw new TypeError(callback + ' is not a function')
}
// 通过this得到调用者arr
const arr = this
// 确定循环变量
let index = 0
// 循环遍历给每个数组元素调用callback
while (index < arr.length) {
// 判断是否存在这个项
if (index in arr) {
// 通过call将this指向thisArg,并且传入3个参数
callback.call(thisArg, arr[index], index, arr)
}
index++
}
}
Object.myAssign = function (target, ...source) {
if ([null, undefined].includes(target)) {
throw new TypeError('Cannot convert undefined or null to object')
}
let result = Object(target)
source.forEach(function (obj) {
if (obj) {
for (let key in obj) {
if (Object.prototype.hasOwnProperty.call(obj,key)) {
result[key] = obj[key]
}
}
}
})
return result
}
Function.prototype.myCall = function (context, ...arg) {
const ctx = context || window
ctx.fn = this
const result = ctx.fn(...arg)
delete ctx.fn
return result;
}
//es6
Function.prototype.myCall = function (thisArg, ...argArray) {
thisArg.fn=this
const result=thisArg.fn(...argArray)
Reflect.deleteProperty(thisArg,'fn')
return result
}
Function.prototype.myApply = function (context, arg) {
const ctx = context || window
ctx.fn = this
const result = Array.isArray(arg) ? ctx.fn(...arg) : ctx.fn()
delete ctx.fn
return result;
}
//
Function.prototype.myApply = function (thisArg, ...argArray) {
thisArg.fn=this
//判断argArray类数组或者数组
thisArg.fn(argArray)
Reflect.deleteProperty(thisArg,'fn')
}
//使用apply
Function.prototype.myBind = function (ctx) {
const fn = this;
return function (...arg) {
return fn.apply(ctx,...arg);
};
};
//构造函数
Function.prototype.myBind = function (context, ...args) {
const ctx = context
const _this = this
const F = function () {
}
const ret = function (..._args) {
if (this instanceof F) {
return new _this(...args, ..._args)
}
return _this.apply(context, args.concat(_args))
}
F.prototype = this.prototype
ret.prototype = new F()
return ret;
}
//不使用apply
Function.prototype.myBind = function (context, ...arg) {
const ctx = context || window
const fn = Symbol()
ctx[fn] = this
return function (..._arg) {
const result = ctx[fn](...arg, ..._arg)
delete ctx[fn]
return result
}
}
Function.prototype.myBind = function (context, ...args) {
const ctx = context
const fn = Symbol()
ctx[fn] = this
const F = function () {}
const ret = function (..._args) {
if (this instanceof F) {
const result = new ctx[fn](...args, ..._args)
delete ctx[fn]
return result
}
const result = ctx[fn](...args, ..._args)
delete ctx[fn]
return result
}
F.prototype = this.prototype
ret.prototype = new F()
return ret;
}
String.prototype.myTrim=function () {
return this.replace(/^\s\s*/,'').replace(/\s\s*$/,'')
}
function myNew(fn,...args) {
let obj = {}
obj.__proto__ = fn.prototype
let result = fn.apply(obj,args)
return result instanceof Object ? result : obj
}
function myNew(fn,...args) {
let obj = Object.create(fn.prototype)
let result = fn.apply(obj,args)
return result instanceof Object ? result : obj
}
function myInstanceof(child, parent) {
let proto = Object.getPrototypeOf(child);
let prototype = parent.prototype
while (proto) {
if (proto === prototype) {
return true;
}
proto = Object.getPrototypeOf(proto);
}
return false;
}
const curry = (fn, ...args) =>
args.length >= fn.length
? fn(...args)
: (..._args) => curry(fn, ...args, ..._args);
const curry = (fn, ...args) => args.length < fn.length ? curry.bind(null, fn, ...args) : fn(...args);
Function.prototype.uncurrying = function() {
var self = this;
return function() {
return Function.prototype.call.apply(self,arguments)
};
}
function debounce(fn,delay=1000) {
let timer=null
return function (...arg) {//不能用箭头函数,不然上下文不对
if(timer){
clearTimeout(timer)
}
timer=setTimeout(()=>{
clearTimeout(timer)
fn.apply(this,arg)
timer = null
},delay)
}
}
function throttle(fn, delay) {
let timer = null;
return function(...args) {
if (timer) return;
timer = setTimeout(() => {
clearTimeout(timer);
timer = null;
fn.apply(this, args);
}, delay);
};
}
const throttle = (func, delay) => {
let startTime = Date.now();
return function(...args) {
const currentTime = Date.now();
if (delay <= (currentTime - startTime)) {
func.apply(this, args);
startTime = Date.now();
}
};
};
function list2tree(list) {
const option = {id: 'id', pid: 'pid', children: 'children'};
const a=list.reduce((prev, curr) => {
const obj = list.find((item) => item[option.id] === curr[option.pid]);
if (obj) {
!Object.prototype.hasOwnProperty.call(obj, option.children) && (obj[option.children] = []);
obj[option.children].push(curr);
} else {
prev.push(curr);
}
return prev;
}, []);
console.log(a)
}
function once(fn) {
let ret
return function (...args) {
if (!fn) return ret
ret = fn(...args)
fn = undefined
return ret
}
}