Skip to content

Commit

Permalink
clone & isRegExp & isDate
Browse files Browse the repository at this point in the history
  • Loading branch information
saqqdy committed Nov 6, 2023
1 parent 6cb78bb commit b411eaf
Show file tree
Hide file tree
Showing 11 changed files with 354 additions and 137 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Change logs

## 2023.11.06 v5.15.0

1. new `clone` function, see: [clone](https://github.com/saqqdy/js-cool#clone)
2. new `isDate` function, see: [isDate](https://github.com/saqqdy/js-cool#isdate)
3. new `isRegExp` function, see: [isRegExp](https://github.com/saqqdy/js-cool#isregexp)

## 2023.11.01 v5.14.1

1. docs work
Expand Down
5 changes: 4 additions & 1 deletion README-zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ const functionList = {
isPlainObject, // 是否plainObject
isDarkMode, // 是否暗色模式
isObject, // 是否object类型
isDate, // 是否日期类型
isRegExp, // 是否正则类型
isArray, // 判断是否数组
isIterable, // 判断是否可迭代对象
inBrowser, // 判断是否在浏览器端运行
Expand Down Expand Up @@ -141,7 +143,8 @@ const functionList = {
promiseFactory, // 将一个对象转换为promise like api
fixNumber, // 截取小数点后几位,不足的不补0
mapTemplate, // 替换模板字符串的特定数据
extend, // 深拷贝
extend, // 深拷贝&合并对象
clone, // 深拷贝 (不支持Buffer、Promise、Set、Map)
delay, // 防抖节流
getType, // 获取目标类型
getFileType, // 根据链接后缀判断文件类型
Expand Down
353 changes: 219 additions & 134 deletions README.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "js-cool",
"description": "Collection of common JavaScript / TypeScript utilities",
"version": "5.14.1",
"version": "5.15.0",
"packageManager": "[email protected]",
"main": "dist/index.cjs.js",
"module": "dist/index.esm-bundler.js",
Expand Down
69 changes: 69 additions & 0 deletions src/clone.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import isArray from './isArray'
import isDate from './isDate'
import isRegExp from './isRegExp'

/**
* deep clone (Buffer, Promise, Set, Map are not supported)
*
* @example
* ```js
* const source = { a: 100, reg: /\d+/g, arr: [1, 2] }
* const res = clone(source)
* // { a: 100, reg: /\d+/g, arr: [1, 2] }
* ```
* @since 5.15.0
* @param parent - source object
* @returns - new object
*/
function clone<T = any>(parent: T): T {
// handle regexp
const getRegExp = (reg: RegExp) => {
let flags = ''
if (reg.global) flags += 'g'
if (reg.ignoreCase) flags += 'i'
if (reg.multiline) flags += 'm'

return flags
}
// Maintain two arrays of circular references
const parents: any[] = []
const children: any[] = []

const _clone = <P = any>(parent: P): P => {
if (parent === null || typeof parent !== 'object') return parent

let child, proto

if (isArray(parent)) {
child = []
} else if (isRegExp(parent)) {
child = new RegExp(parent.source, getRegExp(parent))
if (parent.lastIndex) child.lastIndex = parent.lastIndex
} else if (isDate(parent)) {
child = new Date(parent.getTime())
} else {
proto = Object.getPrototypeOf(parent)
child = Object.create(proto)
}

// Handling circular references
const index = parents.indexOf(parent)

// If this object exists in the parent array, it has already been referenced, so return it directly.
if (index !== -1) return children[index]

parents.push(parent)
children.push(child)

for (const i in parent) {
// recursive
child[i] = _clone(parent[i])
}

return child
}

return _clone(parent)
}

export default clone
2 changes: 1 addition & 1 deletion src/extend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ function extendObject(target: ExtendData, source: ExtendData, deep: boolean): vo
}

/**
* extend greedy
* deep copy & merge objects
*
* @since 1.0.2
* @param target - boolean | ExtendData
Expand Down
6 changes: 6 additions & 0 deletions src/index.default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import isExitsVariable from './isExitsVariable'
import isEqual from './isEqual'
import isWindow from './isWindow'
import isObject from './isObject'
import isDate from './isDate'
import isRegExp from './isRegExp'
import isArray from './isArray'
import isIterable from './isIterable'
import inBrowser from './inBrowser'
Expand Down Expand Up @@ -81,6 +83,7 @@ import promiseFactory from './promiseFactory'
import fixNumber from './fixNumber'
import mapTemplate from './mapTemplate'
import extend from './extend'
import clone from './clone'
import delay from './delay'
import getType from './getType'
import getFileType from './getFileType'
Expand Down Expand Up @@ -167,6 +170,7 @@ export default {
encodeBase64,
encodeUtf8,
extend,
clone,
fillIPv6,
fixNumber,
mapTemplate,
Expand Down Expand Up @@ -204,6 +208,8 @@ export default {
isEqual,
isWindow,
isObject,
isDate,
isRegExp,
isArray,
isIterable,
isPlainObject,
Expand Down
6 changes: 6 additions & 0 deletions src/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const {
encodeBase64,
encodeUtf8,
extend,
clone,
fillIPv6,
fixNumber,
mapTemplate,
Expand Down Expand Up @@ -78,6 +79,8 @@ const {
isEqual,
isWindow,
isObject,
isDate,
isRegExp,
isArray,
isIterable,
isPlainObject,
Expand Down Expand Up @@ -159,6 +162,7 @@ export {
encodeBase64,
encodeUtf8,
extend,
clone,
fillIPv6,
fixNumber,
mapTemplate,
Expand Down Expand Up @@ -200,6 +204,8 @@ export {
isEqual,
isWindow,
isObject,
isDate,
isRegExp,
isArray,
isIterable,
isPlainObject,
Expand Down
3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ export {
} from './isPlainObject'
export { default as isDarkMode } from './isDarkMode'
export { default as isObject } from './isObject'
export { default as isDate } from './isDate'
export { default as isRegExp } from './isRegExp'
export { default as isArray } from './isArray'
export { default as isIterable } from './isIterable'
export { default as inBrowser } from './inBrowser'
Expand Down Expand Up @@ -112,6 +114,7 @@ export { default as promiseFactory } from './promiseFactory'
export { default as fixNumber } from './fixNumber'
export { default as mapTemplate } from './mapTemplate'
export { default as extend, ExtendArrayData, ExtendObjectData, ExtendData } from './extend'
export { default as clone } from './clone'
export { default as delay } from './delay'
export { default as getType } from './getType'
export { default as getFileType } from './getFileType'
Expand Down
21 changes: 21 additions & 0 deletions src/isDate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import getType from './getType'

/**
* Determine if target is Date
*
* @example
* ```js
* const now = new Date()
*
* isDate(now)
* // true
* ```
* @since 5.15.0
* @param target - any target
* @returns - target is Date
*/
function isDate(target: any): target is Date {
return target && getType(target) === 'date'
}

export default isDate
18 changes: 18 additions & 0 deletions src/isRegExp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import getType from './getType'

/**
* Determine if target is RegExp
*
* @example
* ```js
* isRegExp(/\d/) // true
* ```
* @since 5.15.0
* @param target - any target
* @returns - target is RegExp
*/
function isRegExp(target: any): target is RegExp {
return target && getType(target) === 'regexp'
}

export default isRegExp

0 comments on commit b411eaf

Please sign in to comment.