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

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++) {// 将返回值存储起来,最后返回; 当然函数默认返回undefinedresult.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)) {// 相当于循环后存储keyresult.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

相关文章:

js常见函数实现

文章目录 一、数组Array1、forEach2、filter3、map4、reduce5、find6、findIndex7、includes8、join 二、对象Object1、Object.keys2、深复制 js环境中有很多工具函数&#xff0c;比如es6添加了很多新的属性和方法&#xff0c;这些方法也可以自定义实现&#xff0c;但是官方也提…...

点云3DHarris角点检测算法推导

先回顾2D的Harris角点检测算法推导 自相关矩阵是Harris角点检测算法的核心之一&#xff0c;它通过计算图像局部区域的梯度信息来描述该区域的特征。在推导Harris角点检测算法中的自相关矩阵时&#xff0c;我们首先需要了解自相关矩阵的基本思想和数学背景。 参考 1. 能量函数…...

mysql-binlog的三种模式

MySQL的binlog&#xff08;二进制日志&#xff09;有三种主要模式&#xff0c;分别是Statement、Row和Mixed。这三种模式在记录数据库更改的方式上有显著的区别&#xff0c;以下是对这三种模式的详细解释及对比&#xff1a; 一、Statement模式&#xff08;基于SQL语句的复制&a…...

自动类型推导(auto 和 decltype);右值引用和移动语义

1) 自动类型推导&#xff08;auto 和 decltype&#xff09; 自动类型推导&#xff08;auto&#xff09; 在C11及以后的版本中&#xff0c;auto关键字被引入用于自动类型推导。这意味着编译器会自动推断变量的类型&#xff0c;基于其初始化的表达式。使用auto可以让代码更加简…...

(Linux 系统)进程控制

目录 一、进程创建 1、fork函数初识 二、进程终止 1、正常终止 2、异常终止 三、进程等待 1、进程等待必要性 2、进程等待的方法&#xff1a; 四、获取子进程status 1、基本概念 2、进程的阻塞等待方式 3、进程的非阻塞等待方式 五、进程程序替换 1、六种替换函数…...

【Nativeshell】flutter的pc跨平台框架学习记录<二> 窗口间通信

首先是初始化&#xff1a; 查看Nativeshell的demo代码 // ignore_for_file: undefined_hidden_name, // not in main import package:flutter/material.dart hide MenuItem; import package:nativeshell/nativeshell.dart;import pages/other_window.dart; import pages/plat…...

今日codeforces刷题(1)

一、前言 新栏目&#xff0c;每隔几天就保质保量地刷个10道codeforces题左右的样子 筛选1200-1500难度的题&#xff0c;然后按通过题目的人数降序排列的前10题 二、题目总览 三、具体题目 3.1 25A. IQ test 我的代码 看奇数出现的次数为1还是偶数出现的次数为1&#xff0c…...

【C++算法】20.二分查找算法_x 的平方根

文章目录 题目链接&#xff1a;题目描述&#xff1a;解法C 算法代码&#xff1a;图解 题目链接&#xff1a; 69. x 的平方根 题目描述&#xff1a; 解法 暴力解法&#xff1a; 如果x17 从1&#xff0c;2&#xff0c;3&#xff0c;4&#xff0c;5......这些数里面找他们的平方…...

图像显示的是矩阵的行和列,修改为坐标范围。

x 3; y 3; f1x x^2 y^2; guance1 f1x; F (x, y) sqrt((x.^2 y.^2 - guance1).^2); % 使用点乘 [x, y] meshgrid(0:1:5, 0:1:5); Z F(x, y); figure; imagesc(Z); % 由于 imagesc 使用矩阵索引作为坐标&#xff0c;我们需要手动添加刻度 % 这里我们假设 x 和 y 的范围…...

通义灵码走进北京大学创新课堂丨阿里云云原生 10 月产品月报

云原生月度动态 云原生是企业数字创新的最短路径。 《阿里云云原生每月动态》&#xff0c;从趋势热点、产品新功能、服务客户、开源与开发者动态等方面&#xff0c;为企业提供数字化的路径与指南。 趋势热点 &#x1f947; 通义灵码走进北京大学创新课堂&#xff0c;与 400…...

LeetCode Hot100 1~10

目录 哈希1. 两数之和2. 字母异位词分组3. 最长连续子序列 双指针4. 移动零5. 盛最多水的容器6. 三数之和7. 接雨水 子串8. 无重复字符的最长子串9. 找到字符中所有字母的异位词10. 和为K的子数组 哈希 1. 两数之和 利用哈希表找出当前数字还差多少 看看差值时候在哈希表中即…...

npm 最新国内淘宝镜像地址源 (旧版已不能用)

注意&#xff1a;原域名https://registry.npm.taobao.org/ 在 2022.06.30 号正式下线和停止 DNS 解析 最新地址&#xff1a; #最新地址 淘宝 NPM 镜像站喊你切换新域名啦! npm config set registry https://registry.npmmirror.com 查看镜像使用状态 npm config get registr…...

DepthAI 2.29版本 发布

2024年11月29日 增加在设备运行时使用新的 dai::Device.setCalibration() 更改设备校准能力的方法&#xff0c;并使用 dai::Device.getCalibration() 进行检索校准 1&#x1f343; 新的立体深度预设属性&#xff1a; 预设 面部 高细节 机器人 2&#x1f343; 多项摄像…...

C#反序列化XML时提示XML 文档(1, 1)中有错误

最近在反序列化一个XML时&#xff0c;遇到了如下报错&#xff1a; XML 文档(1, 1)中有错误。 内部异常 XmlException: 根级别上的数据无效。 第 1 行&#xff0c;位置 1。 看描述应该是XML格式的问题&#xff0c;我把XML复制到新建的控制台程序&#xff0c;反序列化又是可以的…...

C# 中的接口:定义行为契约与实现多态性

C#中的接口&#xff08;Interfaces&#xff09;。接口是C#中一个非常重要的特性&#xff0c;它允许定义类型的行为契约&#xff0c;而不指定具体实现。通过接口&#xff0c;可以实现多态性、代码的灵活性和可扩展性。以下是一篇关于C#中接口的文章。 引言 接口&#xff08;Int…...

Redis的基础知识·

Redis是一个基于内存的key-value的结构数据库 基于内存存储 读写性能高适合存储热点数据&#xff08;热点商品 咨询 新闻&#xff09; 开启Redis 首先输入命令 redis-server.exe redis.windows.conf 然后重新打开命令行窗口 输入命令 redis-cli.exe 输入密码 …...

qt QProxyStyle详解

1、概述 QProxyStyle是Qt框架中QStyle类的一个子类&#xff0c;它提供了一种代理机制&#xff0c;允许开发者在不直接修改现有样式&#xff08;QStyle&#xff09;实现的情况下&#xff0c;对样式行为进行定制或扩展。通过继承QProxyStyle&#xff0c;开发者可以重写其虚方法&…...

AWS CLI 操作指南

AWS CLI 操作指南 世间本来就存在许多乐境&#xff0c;只是现代人为世间所累而未能予以关注&#xff0c;也就失去了许多体验乐境的机会。比如&#xff0c;忙里偷闲看云&#xff0c;以悠闲的心看悠闲的云&#xff0c;便是一种极妙的乐境。 本文将介绍如何配置 AWS CLI&#xff0…...

海盗王用golang重写的AccountServer功能

自从用golang重写了海盗王的网关gateserver以来&#xff0c;一直想把accountserver也重写了&#xff0c;但是一直没有进行。 趁上次刚写好那个golang版的更新器&#xff0c;还有些熟悉&#xff0c;于是把原来AccountServer的C代码重写读了个大概。它原版的写得太过于复杂&#…...

如何保证spring boot应用程序的安全性?

保证Spring Boot应用程序的安全性是至关重要的&#xff0c;以下是小编为大家列举的一些关键措施和最佳实践&#xff1a; 文章目录 1. 使用Spring Security2. 安全配置3. 数据加密4. 凭证管理5. 输入验证6. 异常处理7. 定期更新依赖8. 日志监控9. 审计日志10. 安全培训 1. 使用S…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...

django blank 与 null的区别

1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是&#xff0c;要注意以下几点&#xff1a; Django的表单验证与null无关&#xff1a;null参数控制的是数据库层面字段是否可以为NULL&#xff0c;而blank参数控制的是Django表单验证时字…...