当前位置: 首页 > article >正文

js常见函数实现

文章目录

  • 一、数组Array
    • 1、forEach
    • 2、filter
    • 3、map
    • 4、reduce
    • 5、find
    • 6、findIndex
    • 7、includes
    • 8、join
  • 二、对象Object
    • 1、Object.keys
    • 2、深复制

js环境中有很多工具函数,比如es6添加了很多新的属性和方法,这些方法也可以自定义实现,但是官方也提供出来了(这样可以形成规范和一致性),了解为什么要提供这些函数是有必要的。

一、数组Array

公共数据

  const inventory = [
    { name: "芦笋", type: "蔬菜", quantity: 5 },
    { name: "香蕉", type: "水果", quantity: 0 },
    { name: "山羊", type: "肉", quantity: 23 },
    { name: "樱桃", type: "水果", quantity: 5 },
    { name: "鱼", type: "肉", quantity: 22 }
  ];

1、forEach

  // 自定义forEach方法
  Array.prototype.forEachCustom = function (cb) {
    // 这里的this是数组本身;
    if (!Array.isArray(this)) {
      return;
    }

    // 这里的cb是自定义的回调函数;
    if (typeof cb !== "function") {
      return;
    }
    for (let i = 0; i < this.length; i++) {
      // this[i], i, this 三个参数分别表示当前元素,索引,数组本身
      // 大部分功能函数都是这三个参数和顺序
      cb(this[i], i, this);
    }
  };

  // inventory.forEachCustom((item) => { // TEST
  //   console.log(item.name);
  // });

2、filter

  // 自定义filter方法
  Array.prototype.filterCustom = function (cb) {
    // 这里的this是数组本身;
    if (!Array.isArray(this)) {
      return;
    }

    // 这里的cb是自定义的回调函数;
    if (typeof cb !== "function") {
      return;
    }
    const result = [];
    for (let i = 0; i < this.length; i++) {
      // 返回值只是为了做if判断,不用存储;存储的是满足条件的元素
      if (cb(this[i], i, this)) {
        result.push(this[i]);
      }
    }
    return result;
  };

  const resultFilterCustom = inventory.filterCustom((item) => {
    return item.quantity >= 6;
  });
  // console.log("filterCustom", resultFilterCustom); // TEST

3、map

  // 自定义map方法
  Array.prototype.mapCustom = function (cb) {
    // 这里的this是数组本身;
    if (!Array.isArray(this)) {
      return;
    }

    // 这里的cb是自定义的回调函数;
    if (typeof cb !== "function") {
      return;
    }
    const result = [];
    for (let i = 0; i < this.length; i++) {
      // 将返回值存储起来,最后返回; 当然函数默认返回undefined
      result.push(cb(this[i], i, this));
    }
    return result;
  };

  const resultMapCustom = inventory.mapCustom((item) => {
    if (item.quantity >= 6) {
      return item.name;
    }
  });
  // console.log("mapCustom", resultMapCustom); // TEST

4、reduce

  // 自定义reduce方法
  Array.prototype.reduceCustom = function (cb, initialValue) {
    // 这里的this是数组本身;
    if (!Array.isArray(this)) {
      return;
    }

    // 这里的cb是自定义的回调函数;
    if (typeof cb !== "function") {
      return;
    }
    // 每一次循环的结果都会作为下一次循环的初始值; 最后返回出去
    let result = initialValue;
    for (let i = 0; i < this.length; i++) {
      result = cb(result, this[i], i, this);
    }
    return result;
  };

  const resultReduceCustom = inventory.reduceCustom((acc, item) => {
    return acc + item.quantity;
  }, 0);
  // console.log("reduceCustom", resultReduceCustom); // TEST

5、find

  // 自定义find方法
  Array.prototype.findCustom = function (cb) {
    // 这里的this是数组本身;
    if (!Array.isArray(this)) {
      return;
    }

    // 这里的cb是自定义的回调函数;
    if (typeof cb !== "function") {
      return;
    }
    for (let i = 0; i < this.length; i++) {
      // 返回值只是为了做if判断,不用存储;
      // 找到第一个满足条件的元素就返回,找到就停止遍历
      // 有点类似于filter,但是只返回第一个满足条件的元素
      if (cb(this[i], i, this)) {
        return this[i];
      }
    }

    // 如果没有找到,返回undefined
  };

  const resultFindCustom = inventory.findCustom((item) => {
    return item.name === "香蕉";
  });
  // console.log("findCustom", resultFindCustom); // TEST

6、findIndex

  // 自定义findIndex方法
  Array.prototype.findIndexCustom = function (cb) {
    // 这里的this是数组本身;
    if (!Array.isArray(this)) {
      return;
    }

    // 这里的cb是自定义的回调函数;
    if (typeof cb !== "function") {
      return;
    }
    for (let i = 0; i < this.length; i++) {
      // 返回索引,找到第一个满足条件的元素就返回,找到就停止遍历
      // 很类似于find,但是只返回第一个满足条件的元素的索引
      if (cb(this[i], i, this)) {
        return i;
      }
    }

    // 如果没有找到,返回-1
  };

  const resultFindIndexCustom = inventory.findIndexCustom((item) => {
    return item.name === "樱桃";
  });
  // console.log("findIndexCustom", resultFindIndexCustom); // TEST

7、includes

  // 自定义includes方法
  Array.prototype.includesCustom = function (value) {
    for (let i = 0; i < this.length; i++) {
      // 这里默认数组是一维数组; 只是单纯判断值是否存在;
      // 如果是复杂数据,使用find即可;
      if (this[i] === value) {
        return true;
      }
    }
    return false;
  };

  // console.log("includesCustom", [1, 2, 3, 4, 5].includesCustom(2)); // TEST

8、join

  // 自定义join方法
  Array.prototype.joinCustom = function (separator) {
    // 这里的this是数组本身;
    if (!Array.isArray(this)) {
      return;
    }

    // 这里的separator是自定义的分隔符;
    if (typeof separator !== "string") {
      return;
    }
    let result = "";
    for (let i = 0; i < this.length; i++) {
      // 这里默认数组是一维数组;
      // 这里默认separator是空格;
      result += this[i] + separator;
    }
    // 去掉最后一个分隔符;
    return result.slice(0, -1);
  };

  console.log("joinCustom", [1, 2, 3, 4, 5].joinCustom("-")); // TEST

二、对象Object

1、Object.keys

提供了一个案例,获取属性时的原型链问题

  // 简易版继承
  const parentFunc = function () {
    this.name = "张三";
  };
  const childFunc = function () {
    // 继承父类的属性和方法;构造函数继承;
    // 注意调用的时机,会决定实例的属性顺序;比如这里的name属性在age前面
    parentFunc.call(this);
    // 运行时this指向childFunc实例对象(的内存空间);
    this.age = 20;
  };
  parentFunc.prototype.getName = function () {
    return this.name;
  };

  childFunc.prototype = new parentFunc();
  const childObj = new childFunc();

  const keysAll = [];
  const keysOwn = [];
  for (let key in childObj) {
    // 自己的属性和原型链上的属性都会遍历出来;
    // 原型链继承的所有属性 + Object.prototype 挂载的自定义方法
    keysAll.push(key);
    if (childObj.hasOwnProperty(key)) {
      // 自己的属性才会遍历出来;
      keysOwn.push(key);
    }
  }
  console.log("Object.keysCustom", keysAll, keysOwn); // TEST
  // 结果:keysAll = ["name", "age", "getName", "keysCustom"];
  // 结果: keysOwn = ["name", "age"];

  // 自定义Object.keys方法   用于获取对象所有属性名
  Object.prototype.keysCustom = function (obj) {
    if (typeof obj !== "object" || obj === null) {
      return;
    }
    const result = []; // 用于存储结果
    for (let key in obj) {
      // hasOwnProperty表示自身的属性,不包括原型链上的属性
      if (obj.hasOwnProperty(key)) {
        // 相当于循环后存储key
        result.push(key);
      }
    }
    return result;
  };

  const obj = { name: "张三", age: 20, gender: "男" };
  // console.log("Object.keysCustom", Object.keysCustom(obj)); // TEST

2、深复制

  const data = [
    { name: "张三", age: 20, array: [1, 2, 3] },
    { name: "李四", age: 25, array: [4, 5, 6] }
  ];

  const deepClone = (source) => {
    if (typeof source !== "object" || source == null) {
      return source;
    }
    const target = Array.isArray(source) ? [] : {};
    for (const key in source) {
      if (Object.prototype.hasOwnProperty.call(source, key)) {
        if (typeof source[key] === "object" && source[key] !== null) {
          target[key] = deepClone(source[key]);
        } else {
          target[key] = source[key];
        }
      }
    }
    return target;
  };

  console.log("deepCopy", deepClone(data)); // TEST

http://www.kler.cn/a/418118.html

相关文章:

  • Ubuntu24.04初始化教程(包含基础优化、ros2)
  • 二分搜索(三)x的平方根
  • ros sensor_msgs::Imu详细介绍 Eigen::Vector3d 详细介绍
  • 逆向攻防世界CTF系列42-reverse_re3
  • 项目快过:知识蒸馏 | 目标检测 |FGD | Focal and Global Knowledge Distillation for Detectors
  • 【软件工程】期末练习题(1){持续更新中}
  • Ubuntu 操作系统
  • 基于51单片机的心率体温监测报警系统(包括程序、仿真、原理图、流程图)
  • 2024年9月 GESP C++等级考试 真题及解析 三级
  • 理解Java集合的基本用法—Collection:List、Set 和 Queue,Map
  • day03(Linux底层)Tftp服务器环境搭建
  • 43 基于单片机的温度和烟雾检测
  • 计算机的错误计算(一百七十一)
  • jQuery零基础入门速通(下)
  • 新版本PasteSpider开发中专用部署工具介绍(让2GB的服务器也能使用CI/CD,简化你的部署过程)
  • 【ROS 机器人快速入门】
  • Elasticsearch ILM 索引生命周期管理讲解与实战
  • gitignore 不起作用
  • jenkins+github+springboot自动部署
  • w064基于springboot的高校学科竞赛平台
  • Element UI 打包探索【3】
  • bugku-web-login2
  • 【Canvas与图标】蓝色渐变SQL图标
  • 小程序解决大问题-物流系统磁盘爆满问题处理
  • 基于深度学习和卷积神经网络的乳腺癌影像自动化诊断系统(PyQt5界面+数据集+训练代码)
  • git如何快速拉取已经提交的mr进行验证