js手写面试题【附带注释】

简介: js手写面试题【附带注释】

前言

hello world欢迎来到前端的新世界


😜当前文章系列专栏:javaScript

🐱‍👓博主在前端领域还有很多知识和技术需要掌握,正在不断努力填补技术短板。(如果出现错误,感谢大家指出)🌹

💖感谢大家支持!您的观看就是作者创作的动力


数组方法手写

push

Array.prototype.myPush = function(...elements) {
  // 获取当前数组的长度
  const currentLength = this.length;
  // 遍历要添加的元素,并逐个添加到数组末尾
  elements.forEach((element) => {
    this[currentLength] = element;
    currentLength++;
  });
  // 返回新数组的长度
  return this.length;
};
// 使用示例
const arr = [1, 2, 3];
arr.myPush(4, 5);
console.log(arr); // [1, 2, 3, 4, 5]


pop

// 定义一个pop函数
function myPop(arr) {
  // 如果数组为空,直接返回undefined
  if (arr.length === 0) {
    return undefined;
  }
  // 获取数组最后一个元素
  const poppedItem = arr[arr.length - 1];
  // 删除数组最后一个元素
  arr.length = arr.length - 1;
  // 返回被删除的元素
  return poppedItem;
}
// 示例用法
const myArray = [1, 2, 3, 4, 5];
const poppedItem = myPop(myArray);
console.log(poppedItem); // 输出 5
console.log(myArray); // 输出 [1, 2, 3, 4]


shift

// 定义一个shift函数
function myShift(arr) {
  // 如果数组为空,直接返回undefined
  if (arr.length === 0) {
    return undefined;
  }
  // 获取数组第一个元素
  const shiftedItem = arr[0];
  // 移除数组第一个元素
  for (let i = 0; i < arr.length - 1; i++) {
    arr[i] = arr[i + 1];
  }
  arr.length = arr.length - 1;
  // 返回被删除的元素
  return shiftedItem;
}
// 示例用法
const myArray = [1, 2, 3, 4, 5];
const shiftedItem = myShift(myArray);
console.log(shiftedItem); // 输出 1
console.log(myArray); // 输出 [2, 3, 4, 5]


unshift

// 定义一个unshift函数
function myUnshift(arr, ...items) {
  // 获取items的长度
  const len = items.length;
  // 将数组中的元素向后移动,为新的元素腾出位置
  for (let i = arr.length - 1; i >= 0; i--) {
    arr[i + len] = arr[i];
  }
  // 将新元素插入到数组的开头
  for (let i = 0; i < len; i++) {
    arr[i] = items[i];
  }
  // 返回新的数组长度
  return arr.length;
}
// 示例用法
const myArray = [1, 2, 3, 4, 5];
const newLength = myUnshift(myArray, 0, -1);
console.log(newLength); // 输出 7
console.log(myArray); // 输出 [0, -1, 1, 2, 3, 4, 5]


cancat

function myConcat(arr, ...args) {
  // 创建一个新数组,初始值为原数组的所有元素
  const newArr = arr.slice();
  // 遍历参数数组
  for (let i = 0; i < args.length; i++) {
    // 如果参数是数组,将数组中的每个元素添加到新数组中
    if (Array.isArray(args[i])) {
      for (let j = 0; j < args[i].length; j++) {
        newArr.push(args[i][j]);
      }
    } else {
      // 如果参数不是数组,直接添加到新数组中
      newArr.push(args[i]);
    }
  }
  // 返回新数组
  return newArr;
}
// 示例用法
const arr1 = [1, 2];
const arr2 = [3, 4];
const newArr = myConcat(arr1, arr2, 5, [6, 7]);
console.log(newArr); // 输出 [1, 2, 3, 4, 5, 6, 7]


slice

function mySlice(arr, start = 0, end = arr.length) {
  // 创建一个新数组
  const newArr = [];
  // 处理负数的情况
  if (start < 0) {
    start = arr.length + start;
  }
  if (end < 0) {
    end = arr.length + end;
  }
  // 处理 start 和 end 超出数组范围的情况
  start = Math.max(0, start);
  end = Math.min(arr.length, end);
  // 循环从原数组中取出指定范围的元素并添加到新数组中
  for (let i = start; i < end; i++) {
    newArr.push(arr[i]);
  }
  // 返回新数组
  return newArr;
}
// 示例用法
const arr = [1, 2, 3, 4, 5];
const slicedArr = mySlice(arr, 1, 4);
console.log(slicedArr); // 输出 [2, 3, 4]


splice

function mySplice(arr, index, count, ...elements) {
  // 处理负数的情况
  if (index < 0) {
    index = arr.length + index;
  }
  // 计算需要删除的元素的个数
  const numToDelete = Math.min(count, arr.length - index);
  // 创建一个新数组,初始值为原数组中需要删除的元素
  const deletedElements = [];
  for (let i = 0; i < numToDelete; i++) {
    deletedElements.push(arr[index + i]);
  }
  // 从原数组中删除需要删除的元素
  for (let i = index + numToDelete - 1; i >= index; i--) {
    arr.splice(i, 1);
  }
  // 将新元素添加到原数组中指定的位置
  for (let i = 0; i < elements.length; i++) {
    arr.splice(index + i, 0, elements[i]);
  }
  // 返回被删除的元素组成的新数组
  return deletedElements;
}
// 示例用法
const arr = [1, 2, 3, 4, 5];
const deletedElements = mySplice(arr, 1, 2, 6, 7);
console.log(arr); // 输出 [1, 6, 7, 4, 5]
console.log(deletedElements); // 输出 [2, 3]


forEach

function myForEach(arr, callback) {
  for (let i = 0; i < arr.length; i++) {
    // 调用回调函数,传入当前元素、当前索引和原数组
    callback(arr[i], i, arr);
  }
}
// 示例用法
const arr = [1, 2, 3];
myForEach(arr, (item, index, array) => {
  console.log(item); // 输出每个元素
  console.log(index); // 输出每个元素的索引
  console.log(array); // 输出原数组
});


map

function myMap(arr, callback) {
  const result = [];
  for (let i = 0; i < arr.length; i++) {
    // 调用回调函数,传入当前元素、当前索引和原数组
    const newItem = callback(arr[i], i, arr);
    // 将回调函数的返回值添加到新数组中
    result.push(newItem);
  }
  return result;
}
// 示例用法
const arr = [1, 2, 3];
const doubled = myMap(arr, (item, index, array) => {
  return item * 2;
});
console.log(doubled); // 输出 [2, 4, 6]


reduce

function myReduce(arr, callback, initialValue) {
  let accumulator = initialValue === undefined ? arr[0] : initialValue;
  for (let i = initialValue ? 0 : 1; i < arr.length; i++) {
    // 调用回调函数,传入累加器、当前元素、当前索引和原数组
    accumulator = callback(accumulator, arr[i], i, arr);
  }
  return accumulator;
}
// 示例用法
const arr = [1, 2, 3, 4, 5];
const sum = myReduce(arr, (accumulator, item, index, array) => {
  return accumulator + item;
});
console.log(sum); // 输出 15


find

function myFind(arr, callback) {
  for (let i = 0; i < arr.length; i++) {
    if (callback(arr[i], i, arr)) {
      return arr[i];
    }
  }
  return undefined;
}
// 示例用法
const arr = [1, 2, 3, 4, 5];
const result = myFind(arr, (item) => {
  return item > 3;
});
console.log(result); // 输出 4


手写订阅发布

class Subject {
    constructor() {
        this.observe = [];
    }
    // 添加观察者
    addObserver(observer){
        this.observe.push(observer)
    }
    // 删除观察者
    removeObserver(observer){
        this.observe = this.observe.filter(obs => obs !== observer)
    }
    // 状态变化
    notfiy(data){
        this.observe.forEach(observer=>{
            observer.update(data)
        })
    }
}
class Observer {
    update(data){
        console.log(`数据:${data}`)
    }
}
const subject = new Subject()
const objectone = new Observer()
const objecttwo = new Observer()
subject.addObserver(objectone)
subject.addObserver(objecttwo)
subject.removeObserver(objecttwo)
subject.notfiy("hello word lpz")


手写单例模式

var Singleton = (function() {
  // 实例变量,用于存储单例实例
  var instance;
  // 单例对象的构造函数
  function Singleton() {
    // 在这里可以初始化单例对象
    this.name = "Singleton Instance";
  }
  // 获取单例实例的方法
  Singleton.getInstance = function() {
    // 如果实例不存在,则创建新实例并赋值给 instance
    if (!instance) {
      instance = new Singleton();
    }
    // 返回单例实例
    return instance;
  };
  // 返回构造函数,使其可以像类一样使用,但无法通过 new Singleton() 实例化
  return Singleton;
})();
// 测试单例模式
var instance1 = Singleton.getInstance();
var instance2 = Singleton.getInstance();
// 由于是单例模式,instance1 和 instance2 应该是相同的实例
console.log(instance1 === instance2); // 输出 true


后言

创作不易,要是本文章对广大读者有那么一点点帮助 不妨三连支持一下,您的鼓励就是博主创作的动力


目录
相关文章
|
2月前
|
JSON JavaScript 前端开发
Javascript基础 86个面试题汇总 (附答案)
该文章汇总了JavaScript的基础面试题及其答案,涵盖了JavaScript的核心概念、特性以及常见的面试问题。
47 3
|
2月前
|
前端开发 JavaScript
JavaScript 面试系列:如何理解 ES6 中 Generator ?常用使用场景有哪些?
JavaScript 面试系列:如何理解 ES6 中 Generator ?常用使用场景有哪些?
|
3月前
|
JavaScript 前端开发
常见的JS面试题
【8月更文挑战第5天】 常见的JS面试题
60 3
|
4天前
|
JSON JavaScript 前端开发
[JS]面试官:你的简历上写着熟悉jsonp,那你说说它的底层逻辑是怎样的?
本文介绍了JSONP的工作原理及其在解决跨域请求中的应用。首先解释了同源策略的概念,然后通过多个示例详细阐述了JSONP如何通过动态解释服务端返回的JavaScript脚本来实现跨域数据交互。文章还探讨了使用jQuery的`$.ajax`方法封装JSONP请求的方式,并提供了具体的代码示例。最后,通过一个更复杂的示例展示了如何处理JSON格式的响应数据。
13 2
[JS]面试官:你的简历上写着熟悉jsonp,那你说说它的底层逻辑是怎样的?
|
22天前
|
Web App开发 JavaScript 前端开发
前端Node.js面试题
前端Node.js面试题
|
2月前
|
JSON JavaScript 前端开发
如何使用代码注释:关于JavaScript与TypeScript
TSDoc是一种标准化TypeScript代码文档注释的规范,使不同工具能无干扰地提取内容。它包括多种标记,如@alpha、@beta等发布阶段标记;@decorator、@deprecated等功能标记;@defaultValue、@eventProperty等描述标记;@example、@experimental等示例与实验性标记;@inheritDoc、@internal等引用与内部标记;@label、@link等链接标记;@override、@sealed等修饰符标记;以及@packageDocumentation、@param、
42 5
|
3月前
|
存储 JavaScript 前端开发
2022年前端js面试题
2022年前端js面试题
37 0
|
3月前
|
JavaScript 前端开发 程序员
JS小白请看!一招让你的面试成功率大大提高——规范代码
JS小白请看!一招让你的面试成功率大大提高——规范代码
|
3月前
|
JavaScript 前端开发 UED
小白请看! 大厂面试题 :如何用JS实现瀑布流
小白请看! 大厂面试题 :如何用JS实现瀑布流
|
3月前
|
存储 JavaScript 前端开发
JS浅拷贝及面试时手写源码
JS浅拷贝及面试时手写源码