You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
727 lines
20 KiB
727 lines
20 KiB
class Tools {
|
|
/**
|
|
* 判断一个对象是否为 undefined
|
|
* @param obj 对象
|
|
* @returns 对象是否为 undefined
|
|
*/
|
|
public static isUndefined(obj: any): boolean {
|
|
return typeof obj === 'undefined';
|
|
}
|
|
|
|
/**
|
|
* 判断一个对象是否为 null 或者 undefined
|
|
* @param obj 对象
|
|
* @returns 对象是否为 null 或者 undefined
|
|
*/
|
|
public static isUndefinedOrNull(obj: any): boolean {
|
|
return obj === null || typeof obj === 'undefined';
|
|
}
|
|
|
|
/**
|
|
* 判断一个对象是否为 null 或者 undefined 或者空字符串
|
|
* @param obj 对象
|
|
* @returns 对象是否为 null 或者 undefined 或者 空字符串
|
|
*/
|
|
public static isEmpty(obj: any): boolean {
|
|
return obj == null || typeof obj == 'undefined' || obj == '';
|
|
}
|
|
|
|
/**
|
|
* 判断一个对象是否是对象类型
|
|
* @param obj 对象
|
|
* @returns 对象是否是对象类型
|
|
*/
|
|
public static isObject(obj: any): boolean {
|
|
return !Tools.isEmpty(obj) && typeof obj === 'object';
|
|
}
|
|
|
|
/**
|
|
* 判断一个对象是否是数组
|
|
* @param obj 对象
|
|
* @returns 对象是否是数组
|
|
*/
|
|
public static isArray(obj: any): boolean {
|
|
return !Tools.isEmpty(obj) && Array.isArray(obj);
|
|
}
|
|
|
|
/**
|
|
* 判断给定的日期是否是当前日期
|
|
* @param date 日期
|
|
* @returns 判断日期是否是当前日期
|
|
*/
|
|
public static isCurrentDay(date: Date): boolean {
|
|
return new Date().toISOString().slice(0, 10) === date.toISOString().slice(0, 10);
|
|
}
|
|
|
|
/**
|
|
* 判断一个日期是否在两个日期之间
|
|
* @param min 下边界日期
|
|
* @param max 上边界日期
|
|
* @param date 日期
|
|
* @returns 判断日期是否在两个日期之间
|
|
*/
|
|
public static isBetweenTwoDates(min: Date, max: Date, date: Date): boolean {
|
|
return date.getTime() >= min.getTime() && date.getTime() <= max.getTime();
|
|
}
|
|
|
|
/**
|
|
* 判断一个日期是否在周末
|
|
* @param date 日期
|
|
* @returns 日期是否在周末
|
|
*/
|
|
public static isWeekend(date: Date): boolean {
|
|
return date.getDay() === 6 || date.getDay() === 0;
|
|
}
|
|
|
|
/**
|
|
* 判断一个日期是否在某年内
|
|
* @param date 日期
|
|
* @param year 年
|
|
* @returns 日期是否在某年内
|
|
*/
|
|
public static isInAYear(date: Date, year: number): boolean {
|
|
return date.getUTCFullYear() === new Date(`${year}`).getUTCFullYear();
|
|
}
|
|
|
|
/**
|
|
* 将 24 小时转换为 am. 或 pm. 格式
|
|
* @param h 小时
|
|
* @returns 转换后的字符串
|
|
*/
|
|
public static toAMPMFormat(h: number): string {
|
|
return `${h % 12 === 0 ? 12 : h % 12}${h < 12 ? ' am.' : ' pm.'}`;
|
|
}
|
|
|
|
/**
|
|
* 将句子的第一个字母大写
|
|
* @param param0 字符串
|
|
* @returns 第一个字母大写后的字符串
|
|
*/
|
|
public static capitalize([first, ...rest]: any): string {
|
|
return `${first.toUpperCase()}${rest.join('')}`;
|
|
}
|
|
|
|
/**
|
|
* 将句子的第一个字母小写
|
|
* @param param0 字符串
|
|
* @returns 第一个字母小写后的字符串
|
|
*/
|
|
public static lowercaseFirst([first, ...rest]: any): string {
|
|
return `${first.toLowerCase()}${rest.join('')}`;
|
|
}
|
|
|
|
/**
|
|
* 将英文字母转成对应的 emoji 形式
|
|
* @param c 字母
|
|
* @returns emoji 字母
|
|
*/
|
|
public static letterToEmoji(c: string): string {
|
|
return String.fromCodePoint(c.toLowerCase().charCodeAt(0) + 127365);
|
|
}
|
|
|
|
/**
|
|
* 判断一个字符串是不是回文
|
|
* @param str 字符串
|
|
* @returns 字符串是不是回文
|
|
*/
|
|
public static isPalindrome(str: string): boolean {
|
|
return str.toLowerCase() === str.toLowerCase().split('').reverse().join('');
|
|
}
|
|
|
|
/**
|
|
* 计算一个数的阶乘
|
|
* @param n 数
|
|
* @returns 一个数的阶乘
|
|
*/
|
|
public static getFactorial(n: number): number {
|
|
return n <= 1 ? 1 : n * Tools.getFactorial(n - 1);
|
|
}
|
|
|
|
/**
|
|
* 计算一个斐波那契数列第 N 项
|
|
* @param n N 项
|
|
* @param memo
|
|
* @returns
|
|
*/
|
|
public static getFibonacci(n: number, memo: number[]): number {
|
|
return memo[n] || (n <= 2 ? 1 : (memo[n] = Tools.getFibonacci(n - 1, memo) + Tools.getFibonacci(n - 2, memo)));
|
|
}
|
|
|
|
/**
|
|
* 复制数组
|
|
* @param arr 数组
|
|
* @returns 复制后的数组
|
|
*/
|
|
public static copyToArray(arr: any[]): any[] {
|
|
return [...arr];
|
|
}
|
|
|
|
/**
|
|
* 数组去重
|
|
* @param arr 数组
|
|
* @returns 去重后的数组
|
|
*/
|
|
public static getUnique(arr: any[]): any[] {
|
|
return [...new Set(arr)];
|
|
}
|
|
|
|
/**
|
|
* 生成随机数字数组
|
|
* @param arr 数组
|
|
* @returns 生成随机数字数组
|
|
*/
|
|
public static shuffle(arr: number[]): number[] {
|
|
return arr.sort(() => Math.random() - 0.5);
|
|
}
|
|
|
|
/**
|
|
* 反转字符串
|
|
* @param str 字符串
|
|
* @returns 反转后的字符串
|
|
*/
|
|
public static reverseString(str: string): string {
|
|
return str.split('').reverse().join('');
|
|
}
|
|
|
|
/**
|
|
* 检查两个数组是否包含相同的值
|
|
* @param arr1 第一个数组
|
|
* @param arr2 第二个数组
|
|
* @returns 两个数组是否包含相同的值
|
|
*/
|
|
public static containSameValues(arr1: any[], arr2: any[]): boolean {
|
|
return arr1.sort().join(',') === arr2.sort().join(',');
|
|
}
|
|
|
|
/**
|
|
* 温度转换(摄氏度->华氏度)
|
|
* 华氏度 = 32 + 摄氏度× 1.8
|
|
* @param celsius 摄氏度
|
|
* @returns 华氏度
|
|
*/
|
|
public static toFahrenheit(celsius: number): number {
|
|
return (celsius * 9) / 5 + 32;
|
|
}
|
|
|
|
/**
|
|
* 温度转换(华氏度->摄氏度)
|
|
* 华氏度 = 32 + 摄氏度× 1.8
|
|
* @param fahrenheit 华氏度
|
|
* @returns 摄氏度
|
|
*/
|
|
public static toCelsius(fahrenheit: number): number {
|
|
return ((fahrenheit - 32) * 5) / 9;
|
|
}
|
|
|
|
/**
|
|
* 清除浏览器中的所有 cookie
|
|
* @returns void
|
|
*/
|
|
public static clearAllCookies(): void {
|
|
document.cookie.split(';').forEach((c) => (document.cookie = c.replace(/^ +/, '').replace(/=.*/, `=;expires=${new Date().toUTCString()};path=/`)));
|
|
}
|
|
|
|
/**
|
|
* 检查函数是否为异步函数
|
|
* @param f 函数
|
|
* @returns 函数是否为异步函数
|
|
*/
|
|
public static isAsyncFunction(f: any): boolean {
|
|
return Object.prototype.toString.call(f) === '[object AsyncFunction]';
|
|
}
|
|
|
|
/**
|
|
* 判断代码是否在浏览器中运行
|
|
* @returns 代码是否在浏览器中运行
|
|
*/
|
|
public static runningInBrowser(): boolean {
|
|
return typeof window === 'object' && typeof document === 'object';
|
|
}
|
|
|
|
/**
|
|
* 判断代码是否在 Node 中运行
|
|
* @returns 代码是否在 Node 中运行
|
|
*/
|
|
public static runningInNode(): boolean {
|
|
return typeof process !== 'undefined' && process.versions != null && process.versions.node != null;
|
|
}
|
|
|
|
/**
|
|
* 判断系统是否是暗模式
|
|
* @returns 系统是否是暗模式
|
|
*/
|
|
public static isDarkMode(): boolean {
|
|
return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
}
|
|
|
|
/**
|
|
* 将 dom 元素滚动到顶部
|
|
* @param element dom 元素
|
|
* @returns void
|
|
*/
|
|
public static toTop(element: HTMLElement): void {
|
|
element.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
}
|
|
|
|
/**
|
|
* 将 dom 元素滚动到底部
|
|
* @param element dom 元素
|
|
* @returns void
|
|
*/
|
|
public static toBottom(element: HTMLElement): void {
|
|
element.scrollIntoView({ behavior: 'smooth', block: 'end' });
|
|
}
|
|
|
|
/**
|
|
* 将 JSON 转换为 MAP
|
|
* @param json json 字符串
|
|
* @returns MAP
|
|
*/
|
|
public static jsonToMap(json: string): Map<any, any> {
|
|
return new Map(Object.entries(JSON.parse(json)));
|
|
}
|
|
|
|
/**
|
|
* 对象转 json 字符串
|
|
* @param obj 对象
|
|
* @returns json 字符串
|
|
*/
|
|
public static object2Json(obj: any): string | null {
|
|
return Tools.isEmpty(obj) ? null : JSON.stringify(obj);
|
|
}
|
|
|
|
/**
|
|
* json 字符串转对象
|
|
* @param json json 字符串
|
|
* @returns 对象
|
|
*/
|
|
public static json2Object(json: string): any {
|
|
return Tools.isEmpty(json) ? null : JSON.parse(json);
|
|
}
|
|
|
|
/**
|
|
* 通过连接字符串连接数组
|
|
* 使用说明:
|
|
* const array =['001','002','003'];
|
|
* const joined =join(array); // joined='001-002-003'
|
|
*
|
|
* const objArray =[{name:'001',age:10},{name:'002',age:20}];
|
|
* const joined =join(array,'-','name'); // joined='001-002'
|
|
* @param array 数组
|
|
* @param joiner 连接字符串
|
|
* @param propertyName 属性名, 可选参数, 如果数组元素为 js 对象,可通过该参数指定需要连接的 js 对象的属性,如果传入 null ,则直接连接数组元素
|
|
* @returns 通过连接字符串连接数组
|
|
*/
|
|
public static join(array: any, joiner: string, propertyName?: string): string {
|
|
if (Tools.isEmpty(array)) {
|
|
return '';
|
|
}
|
|
propertyName = propertyName || '';
|
|
if (Array.isArray(array)) {
|
|
let result = '';
|
|
if (array.length > 0) {
|
|
for (let i = 0; i < array.length; i++) {
|
|
if (propertyName == '') {
|
|
result += array[i] + joiner;
|
|
} else {
|
|
result += array[i][propertyName] + joiner;
|
|
}
|
|
}
|
|
}
|
|
if (result != '') {
|
|
result = result.substring(0, result.length - 1);
|
|
}
|
|
return result;
|
|
} else {
|
|
return array;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 深度克隆对象
|
|
* @param target 需要克隆对象
|
|
* @returns 克隆后的对象
|
|
*/
|
|
public static deepClone(target: any): any {
|
|
const map = new WeakMap();
|
|
|
|
function isObject(target: any) {
|
|
return (typeof target === 'object' && target) || typeof target === 'function';
|
|
}
|
|
|
|
function clone(data: any) {
|
|
if (!isObject(data)) {
|
|
return data;
|
|
}
|
|
if ([Date, RegExp].includes(data.constructor)) {
|
|
return new data.constructor(data);
|
|
}
|
|
if (typeof data === 'function') {
|
|
return new Function('return ' + data.toString())();
|
|
}
|
|
const exist = map.get(data);
|
|
if (exist) {
|
|
return exist;
|
|
}
|
|
if (data instanceof Map) {
|
|
const result = new Map();
|
|
map.set(data, result);
|
|
data.forEach((val, key) => {
|
|
if (isObject(val)) {
|
|
result.set(key, clone(val));
|
|
} else {
|
|
result.set(key, val);
|
|
}
|
|
});
|
|
return result;
|
|
}
|
|
if (data instanceof Set) {
|
|
const result = new Set();
|
|
map.set(data, result);
|
|
data.forEach((val) => {
|
|
if (isObject(val)) {
|
|
result.add(clone(val));
|
|
} else {
|
|
result.add(val);
|
|
}
|
|
});
|
|
return result;
|
|
}
|
|
const keys = Reflect.ownKeys(data);
|
|
const allDesc = Object.getOwnPropertyDescriptors(data);
|
|
const result = Object.create(Object.getPrototypeOf(data), allDesc);
|
|
map.set(data, result);
|
|
keys.forEach((key) => {
|
|
const val = data[key];
|
|
if (isObject(val)) {
|
|
result[key] = clone(val);
|
|
} else {
|
|
result[key] = val;
|
|
}
|
|
});
|
|
return result;
|
|
}
|
|
|
|
return clone(target);
|
|
}
|
|
|
|
/**
|
|
* 构建 Http Get 请求查询参数 url
|
|
* 使用说明:
|
|
* 1. 键值对数组
|
|
* const params =[
|
|
* {key:'name',value:'姓名'},
|
|
* {key:'年龄',value:20}
|
|
* ];
|
|
* const url =buildHttpQueryString(params); //url ='name=%E5%A7%93%E5%90%8D&%E5%B9%B4%E9%BE%84=20'
|
|
* 2. 简单对象
|
|
* const params ={
|
|
* name:'姓名',
|
|
* 年龄:20
|
|
* };
|
|
* const url =buildHttpQueryString(params); //url ='name=%E5%A7%93%E5%90%8D&%E5%B9%B4%E9%BE%84=20'
|
|
* 3. 对象属性也支持数组
|
|
* const params ={
|
|
* name:'姓名',
|
|
* phone:[
|
|
* '13012345678',
|
|
* '13812345678'
|
|
* ]
|
|
* };
|
|
* const url =buildHttpQueryString(params); //url ='name=%E5%A7%93%E5%90%8D&phone=13012345678,13812345678'
|
|
* @param parameters 查询参数
|
|
* @param encode 编码字符集
|
|
* @returns 编码后的 url
|
|
*/
|
|
public static buildHttpQueryString(parameters: any, encode?: true): string | null {
|
|
if (Tools.isEmpty(parameters)) return null;
|
|
const _parameters: any[] = [];
|
|
if (Tools.isArray(parameters)) {
|
|
//支持以 [{key:'name',value:'姓名'},{key:'age',value:20}] 形式的参数
|
|
for (let i = 0; i < parameters.length; i++) {
|
|
if (encode) {
|
|
_parameters[i] = encodeURIComponent(parameters[i].key) + '=' + encodeURIComponent(parameters[i].value);
|
|
} else {
|
|
_parameters[i] = parameters[i].key + '=' + parameters[i].value;
|
|
}
|
|
}
|
|
return Tools.join(_parameters, '&');
|
|
} else if (Tools.isObject(parameters)) {
|
|
//支持以 {name:'姓名',age:20} 形式的参数
|
|
let i = 0;
|
|
for (const key in parameters) {
|
|
const value = parameters[key];
|
|
if (Tools.isArray(value)) {
|
|
//支持以 {address:['上海','beijing']} 形式的参数
|
|
for (let j = 0; j < value.length; j++) {
|
|
if (encode) {
|
|
value[j] = encodeURIComponent(value[j]);
|
|
}
|
|
}
|
|
if (encode) {
|
|
_parameters[i++] = encodeURIComponent(key) + '=' + Tools.join(value, ',');
|
|
} else {
|
|
_parameters[i++] = key + '=' + Tools.join(value, ',');
|
|
}
|
|
} else {
|
|
if (encode) {
|
|
_parameters[i++] = encodeURIComponent(key) + '=' + encodeURIComponent(parameters[key]);
|
|
} else {
|
|
_parameters[i++] = key + '=' + parameters[key];
|
|
}
|
|
}
|
|
}
|
|
return Tools.join(_parameters, '&');
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 连接两个 URL 组成一个 URL
|
|
* @param url1 第一个 URL
|
|
* @param url2 第二个 URL
|
|
*/
|
|
public static concatUrl(url1: string | null, url2: string | null): string {
|
|
return (Tools.removeUrlSuffixSlash(url1) || '') + '/' + (Tools.removeUrlPrefixSlash(url2) || '');
|
|
}
|
|
|
|
/**
|
|
* 移除 URL 中所有的前导 /
|
|
* @param url url
|
|
* @returns 移除后的 URL
|
|
*/
|
|
public static removeUrlPrefixSlash(url: string | null): string | null {
|
|
if (url) {
|
|
let _url = url;
|
|
while (_url.startsWith('/')) {
|
|
_url = _url.substring(1);
|
|
}
|
|
return _url;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* 移除 URL 中所有的后导 /
|
|
* @param url url
|
|
* @returns 移除后的 URL
|
|
*/
|
|
public static removeUrlSuffixSlash(url: string | null): string | null {
|
|
if (url) {
|
|
let _url = url;
|
|
while (_url.endsWith('/')) {
|
|
_url = _url.substring(0, _url.length - 1);
|
|
}
|
|
return _url;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* 给 dom 元素增加 class
|
|
* @param target dom 元素
|
|
* @param className class 名
|
|
*/
|
|
public static addClassName(target: HTMLElement | null, className: string | null): void {
|
|
if (target && className) {
|
|
const _class = target.getAttribute('class');
|
|
if (_class) {
|
|
const classes = _class.split(' ');
|
|
classes.push(className);
|
|
const clazzSet = [...new Set(classes)];
|
|
target.setAttribute('class', clazzSet.join(' '));
|
|
} else {
|
|
target.setAttribute('class', className);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 移除 dom 元素的 class
|
|
* @param target dom 元素
|
|
* @param className class 名
|
|
*/
|
|
public static removeClassName(target: HTMLElement | null, className: string | null): void {
|
|
if (target && className) {
|
|
const _class = target.getAttribute('class');
|
|
if (_class) {
|
|
let classes = _class.split(' ');
|
|
classes = [...new Set(classes)];
|
|
classes = classes.filter((item) => item !== className);
|
|
target.setAttribute('class', classes.join(' '));
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取页面所有外部引用的 javascript 的 url
|
|
* @returns 页面所有外部引用的 javascript 的 url
|
|
*/
|
|
public static getJavascriptElementUrls(): string[] {
|
|
const result: string[] = [];
|
|
const scripts = document.getElementsByTagName('script');
|
|
for (const script of scripts) {
|
|
const url = script.getAttribute('src');
|
|
if (url) {
|
|
result.push(url);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* 在 dom 中插入 <script src="..."></script> 标签元素
|
|
* @param src javascript url
|
|
* @param target 插入到 dom 中的元素, 如果未指定则插入到 dom 的 head 元素中
|
|
* @param callback 加载成功后回调函数
|
|
*/
|
|
public static appendJavascriptTag(src: string | null, target?: HTMLElement, callback?: any): void {
|
|
if (src) {
|
|
const script = document.createElement('script') as HTMLScriptElement;
|
|
script.type = 'text/javascript';
|
|
script.src = src;
|
|
if (callback) {
|
|
script.onload = callback;
|
|
}
|
|
if (target) {
|
|
target.appendChild(script);
|
|
} else {
|
|
document.head.appendChild(script);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 下载 URL, 创建 iframe, 并在 iframe 中下载资源, 避免页面跳转
|
|
* @param url URL
|
|
*/
|
|
public static download(url: string | null): void {
|
|
if (url) {
|
|
const iframeId = '_download_iframe';
|
|
let iframe = document.getElementById(iframeId) as HTMLIFrameElement;
|
|
if (iframe) {
|
|
iframe.src = url;
|
|
} else {
|
|
iframe = document.createElement('iframe');
|
|
iframe.id = iframeId;
|
|
iframe.src = url;
|
|
iframe.style.display = 'none';
|
|
document.getElementsByTagName('body')[0].appendChild(iframe);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 设置页面标题
|
|
* @param title 页面标题
|
|
*/
|
|
public static setTitile(title: string | null): void {
|
|
if (title) {
|
|
document.title = title;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 设置页面 icon
|
|
* @param iconUrl 页面 icon url 地址
|
|
*/
|
|
public static setFavicon(favicon: string | null): void {
|
|
if (favicon) {
|
|
let faviconElement: HTMLLinkElement = document.querySelector("link[rel*='icon']") as HTMLLinkElement;
|
|
if (faviconElement) {
|
|
console.log(faviconElement.href);
|
|
faviconElement.href = favicon;
|
|
} else {
|
|
faviconElement = document.createElement('link');
|
|
faviconElement.rel = 'shortcut icon';
|
|
faviconElement.href = favicon;
|
|
document.getElementsByTagName('head')[0].appendChild(faviconElement);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 移除 dom 元素
|
|
* @param element dom 元素对象或者 dom 元素 ID
|
|
*/
|
|
public static removeDomElement(element: HTMLElement | string): void {
|
|
if (element) {
|
|
if (Tools.isObject(element)) {
|
|
(element as HTMLElement).parentNode?.removeChild(element as HTMLElement);
|
|
} else {
|
|
const e = document.getElementById(element as string);
|
|
if (e) {
|
|
e.parentNode?.removeChild(e);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 返回在一个数值范围内的数值
|
|
* @param value 数值
|
|
* @param min 数值范围下界
|
|
* @param max 数值范围上界
|
|
* @returns 在数值范围内的数值
|
|
*/
|
|
public static range(value: number, min: number, max: number): number {
|
|
if (value < min) {
|
|
return min;
|
|
} else if (value > max) {
|
|
return max;
|
|
} else {
|
|
return value;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 合并对象,将源对象的属性合并到目标对象上
|
|
* @param target 目标对象
|
|
* @param source 源对象
|
|
*/
|
|
public static mergeObject(target: object, source: object): object {
|
|
if (source && target) {
|
|
for (const property in source) {
|
|
const value = source[property];
|
|
if (Tools.isObject(value) && !Tools.isArray(value)) {
|
|
//正常对象,排除 undefined 和 null
|
|
if (Tools.isUndefinedOrNull(target[property])) {
|
|
target[property] = {};
|
|
}
|
|
Tools.mergeObject(target[property], value);
|
|
} else {
|
|
if (!Tools.isUndefinedOrNull(value)) {
|
|
target[property] = value;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return target;
|
|
}
|
|
|
|
public static objectValueEquals(o1: object | null | undefined, o2: object | null | undefined): boolean {
|
|
if (Tools.isUndefinedOrNull(o1) && Tools.isUndefinedOrNull(o2)) {
|
|
return true;
|
|
}
|
|
if ((!Tools.isUndefinedOrNull(o1) && Tools.isUndefinedOrNull(o2)) || (Tools.isUndefinedOrNull(o1) && !Tools.isUndefinedOrNull(o2))) {
|
|
return false;
|
|
}
|
|
if (o1 === o2) {
|
|
return true;
|
|
}
|
|
for (const p1 in o1) {
|
|
if (o1[p1] != o2[p1]) {
|
|
return false;
|
|
}
|
|
}
|
|
for (const p2 in o2) {
|
|
if (o1[p2] != o2[p2]) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
export { Tools };
|
|
|