手写题

20 阅读3分钟
  1. 字符串反转(不用reserve)
let str = "hello"
console.log(str.split('').reverse().join())

function myReverse(str) {
    let newStr = ''
    for(let i=0;i<str.length;i++){
        newStr = str[i]+ newStr 
    }

    return newStr
}

function myReverse(str) {
    let newStr = ''
    for(let i=str.length-1;i>=0;i--){
        newStr = newStr +str[i]
    }

    return newStr
}
function myReverse(str) {
    let arr = str.split('')
    for(let i=0;i<str.length;i++){
        let left = 0
        let right=str.length-1
        while(left<right){
            [arr[left],arr[right]] = [arr[right],arr[left]]
            left++
            right--
        }
            
    }
    return arr.join('')
}

function myReverse(str){
    let arr = []
    let newStr = ''
    for(let i=0;i<str.length;i++){
        arr.push(str[i])
    }

    while(arr.length){
        newStr += arr.pop()
    }
    return newStr

}
console.log(myReverse(str))
  1. 判断数据类型
判断数据类型
function panduanType(obj){
    return Object.prototype.toString.call(obj).slice(8,-1)
}
console.log(panduanType('22'))
console.log(panduanType(22))
console.log(panduanType([1,3]))
console.log(panduanType({}))
console.log(panduanType(function(){}))
console.log(panduanType(null))
console.log(panduanType(undefined))
console.log(panduanType(BigInt(12121)))
console.log(panduanType(Symbol()))

  1. 比较2个版本号
function compareVersions(v1, v2) {
    const parts1 = v1.split('.').map(Number);
    const parts2 = v2.split('.').map(Number);
    const maxLength = Math.max(parts1.length, parts2.length);
    
    for (let i = 0; i < maxLength; i++) {
      const num1 = parts1[i] || 0; // 如果部分缺失,视为 0
      const num2 = parts2[i] || 0;
      
      if (num1 > num2) return 1;  // v1 > v2
      if (num1 < num2) return -1; // v1 < v2
    }
    
    return 0; // 版本号完全相同
  }
  
  // 使用示例
  console.log(compareVersions("1.2.3", "1.10.0")); // -1 (1.2.3 < 1.10.0)
  console.log(compareVersions("2.0", "2.0.0"));    // 0 (相等)
  console.log(compareVersions("3.5.0", "3.4.9"));  // 1 (3.5.0 > 3.4.9)
  1. promise

function myPromise(constructor){
    let self = this
    self.status = 'pending'
    self.value = undefined
    self.reason = undefined
    function resolve(value){
        if(self.status === 'pending') {
            self.status = 'resolved'
            self.value = value
        }
    } 

    function reject(reason){
        if(self.pending === 'pending') {
            self.status='rejected'
            self.reason=reason
        }
    }

    try{
        constructor(resolve,reject)
    } catch(e){
        reject(e)
    }
}

myPromise.prototype.then = function(onFullFilled, onRejected){
    let self = this
    switch(self.status){
        case 'resolved':
            onFullFilled(self.value)
        case 'rejected':
            onRejected(self.reason)
        default
    }
}
  1. promise.all
function all(array) {
    if(!(array instanceof Array)){
        throw Error('参数必须是数组')
    }
    return new Promise(function(resolve, reject){
        let len = array.length
        if(len === 0) return resolve([]) // 处理空数组情况
        
        let resolvedCount = 0
        let resolvedArr = new Array(len)
        
        for(let i=0; i<len; i++){
            Promise.resolve(array[i]) // 确保处理非Promise值
                .then(function(value){
                    resolvedArr[i] = value
                    resolvedCount++
                    if(resolvedCount === len){
                        resolve(resolvedArr)
                    }
                })
                .catch(function(err){
                    reject(err)
                })
        }
    })
}

// 正确的测试用例
let p1 = Promise.resolve(1)
let p2 = Promise.resolve(2)
let p3 = Promise.resolve(3)

all([p1,p2,p3])
    .then(console.log)  // 应该输出 [1, 2, 3]
    .catch(console.error)

6.promise.race

function promiseRace(array) {
    if(!Array.isArray(array)){
        throw Error('array')
    }
    return new Promise((resolve,reject)=>{
        for(let i of array){
            Promise.resolve(i)
                .then((val)=>{
                    resolve(val)
                })
                .catch((err)=>{
                    reject(err)
                })
        }
    })
}

7.promiseAllsettled


function promiseAllsettled(array){
    if(!Array.isArray(array)){
        throw Error('array')
    }

    return new Promise((resolve, reject)=>{
        let len = array.length
        let result = new Array(len)
        let count = 0
        
        array.forEach((i,index)=>{
            Promise.resolve(i)
                .then((val)=>{
                    result[index] = {status:'onFullfilled',val:val}
                })
                .catch((err)=>{
                    result[index] = {status:'onRejected',err:err}
                })
                .finally(()=>{
                    count++;
                    if(count === len) {
                      resolve(result)  
                    }
                })
        })
    })
}

8.闭包

var test = (function() {
    var z = 5;
    return function(z) {
        console.log(z);
    };
})();

var z = 2;
test(2); 
(function() {
    var z = 3;
    test(3); 
})();
(function(func) {
    var z = 4;
    func(4); 
})(test);
  1. 防抖
function de(func,delay){
    let timer;
    return function(){
        if(timer) {clearTimeout(timer)}
        timer=setTimeout(()=>{
            func.apply(this,arguments)
        },delay)
    }
}

10.节流

function jie(func,delay){
    let lastTime=0
    return function(){
        const now = Data.now()
        if(now-lastTime>delay){
            func.apply(this,arguments)
            lastTime = now
        }
    }
}
  1. 深拷贝
function deepClone(obj){
    let result
    if(typeof obj === 'object'){
        result = obj.contructor === 'Array' ? [] : {}
        for(let i in obj){
            result[i] = typeof obj[i] === 'object' ? deepClone(obj[i]) : obj[i]
        }
    } else {
        result = obj
    }
    return result
}
  1. 数组交集并集
const arr1 = [1, 3, 4, 6, 7]
const arr2 = [2, 5, 3, 6, 1]
let res = new Set()
let arr = new Set(arr2)

function jiaoji(){
    for (let i of arr1) {
        if(arr.has(i)){
            res.add(i)
        }
    }
    return Array.from(res)
}

// console.log(jiaoji())

function bingji(){
    for (let i of arr1) {
        arr.add(i)
    }
    return Array.from(arr)
}
console.log(bingji())

13.把树形结构转换成扁平数组

const tree = [
  {
    id: 1,
    name: 'Root',
    children: [
      {
        id: 2,
        name: 'Child 1',
        children: [{ id: 4, name: 'Grandchild 1', children: [] }],
      },
      {
        id: 3,
        name: 'Child 2',
        children: [],
      },
    ],
  },
];

function treeToArr(tree, parentId = null) {
  let arr = [];
  for (let node of tree) {
    arr.push({
      id: node.id,
      name: node.name,
      parentId: parentId,
    });
    if (node.children && node.children.length > 0) {
      arr.push(...treeToArr(node.children, node.id));
    }
  }
  return arr;
}

console.log(treeToArr(tree));
[
  { id: 1, name: 'Root', parentId: null },
  { id: 2, name: 'Child 1', parentId: 1 },
  { id: 4, name: 'Grandchild 1', parentId: 2 },
  { id: 3, name: 'Child 2', parentId: 1 }
]
  1. 判断类型

function getType(obj) {
    if(obj === 'null') return 'NULL'
    if(obj === 'undefined') return 'undefined' 
    return Object.prototype.toString.call(obj).slice(8,-1)
}
console.log(getType('21'))

  1. instanceof

function myInstanceOf(left, right) {
    let proto = Object.getPrototypeOf(left)
    let prototype = right.prototype

    while(true){
        if(!proto) return false
        if(proto === prototype) return true
        proto = Object.getPrototypeOf(proto)
    }
}

// console.log(myInstanceOf([1,3], Array))
  1. 手写new
function myNew(Con, ...args) {
    let myObj = {}
    Object.setPrototypeOf(myObj, Con.prototype)
    let result = Con.apply(myObj, args)
    return result instanceof Object ? result : myObj
}

function Test(name, age) {
  this.name = name
  this.age = age
}
Test.prototype.say = function() {
    return this.name
}
const aa = myNew(Test, 'xiaomi', 1)
console.log(aa.name)
console.log(aa.age)
console.log(aa.say())