提交 2534a279 编写于 作者: fxy060608's avatar fxy060608

refactor(v3): diff

上级 d1349bb0
...@@ -308,6 +308,45 @@ var serviceContext = (function () { ...@@ -308,6 +308,45 @@ var serviceContext = (function () {
const timerFn = () => fn.apply(this, arguments); const timerFn = () => fn.apply(this, arguments);
timeout = setTimeout(timerFn, delay); timeout = setTimeout(timerFn, delay);
} }
}
/**
* Check if two values are loosely equal - that is,
* if they are plain objects, do they have the same shape?
*/
function looseEqual (a, b) {
if (a === b) return true
const isObjectA = isObject(a);
const isObjectB = isObject(b);
if (isObjectA && isObjectB) {
try {
const isArrayA = Array.isArray(a);
const isArrayB = Array.isArray(b);
if (isArrayA && isArrayB) {
return a.length === b.length && a.every((e, i) => {
return looseEqual(e, b[i])
})
} else if (a instanceof Date && b instanceof Date) {
return a.getTime() === b.getTime()
} else if (!isArrayA && !isArrayB) {
const keysA = Object.keys(a);
const keysB = Object.keys(b);
return keysA.length === keysB.length && keysA.every(key => {
return looseEqual(a[key], b[key])
})
} else {
/* istanbul ignore next */
return false
}
} catch (e) {
/* istanbul ignore next */
return false
}
} else if (!isObjectA && !isObjectB) {
return String(a) === String(b)
} else {
return false
}
} }
const encodeReserveRE = /[!'()*]/g; const encodeReserveRE = /[!'()*]/g;
...@@ -649,7 +688,7 @@ var serviceContext = (function () { ...@@ -649,7 +688,7 @@ var serviceContext = (function () {
const ASYNC_API = ['createBLEConnection']; const ASYNC_API = ['createBLEConnection'];
const CALLBACK_API_RE = /^on/; const CALLBACK_API_RE = /^on|^off/;
function isContextApi (name) { function isContextApi (name) {
return CONTEXT_API_RE.test(name) return CONTEXT_API_RE.test(name)
...@@ -1373,7 +1412,7 @@ var serviceContext = (function () { ...@@ -1373,7 +1412,7 @@ var serviceContext = (function () {
} }
}, },
data: { data: {
type: [Object, String, ArrayBuffer], type: [Object, String, Array, ArrayBuffer],
validator (value, params) { validator (value, params) {
params.data = value || ''; params.data = value || '';
} }
...@@ -1414,6 +1453,9 @@ var serviceContext = (function () { ...@@ -1414,6 +1453,9 @@ var serviceContext = (function () {
value = (value || '').toLowerCase(); value = (value || '').toLowerCase();
params.responseType = Object.values(responseType).indexOf(value) < 0 ? responseType.TEXT : value; params.responseType = Object.values(responseType).indexOf(value) < 0 ? responseType.TEXT : value;
} }
},
withCredentials: {
type: Boolean
} }
}; };
...@@ -2175,7 +2217,9 @@ var serviceContext = (function () { ...@@ -2175,7 +2217,9 @@ var serviceContext = (function () {
valid = t === expectedType.toLowerCase(); valid = t === expectedType.toLowerCase();
if (!valid && t === 'object') { if (!valid && t === 'object') {
valid = value instanceof type; valid = value instanceof type;
} }
} else if (value.byteLength >= 0) {
valid = true;
} else if (expectedType === 'Object') { } else if (expectedType === 'Object') {
valid = isPlainObject(value); valid = isPlainObject(value);
} else if (expectedType === 'Array') { } else if (expectedType === 'Array') {
...@@ -2970,7 +3014,7 @@ var serviceContext = (function () { ...@@ -2970,7 +3014,7 @@ var serviceContext = (function () {
} }
function getScreenInfo () { function getScreenInfo () {
const { resolutionWidth, resolutionHeight } = plus.screen.getCureentSize(); const { resolutionWidth, resolutionHeight } = plus.screen.getCurrentSize();
return { return {
screenWidth: Math.round(resolutionWidth), screenWidth: Math.round(resolutionWidth),
screenHeight: Math.round(resolutionHeight) screenHeight: Math.round(resolutionHeight)
...@@ -3019,7 +3063,7 @@ var serviceContext = (function () { ...@@ -3019,7 +3063,7 @@ var serviceContext = (function () {
function createAudioInstance () { function createAudioInstance () {
const audioId = `${Date.now()}${Math.random()}`; const audioId = `${Date.now()}${Math.random()}`;
const audio = audios[audioId] = plus.audio.createPlayer(''); const audio = audios[audioId] = plus.audio.createPlayer('');
audio.src = ''; audio.src = '';
audio.volume = 1; audio.volume = 1;
audio.startTime = 0; audio.startTime = 0;
...@@ -3093,7 +3137,7 @@ var serviceContext = (function () { ...@@ -3093,7 +3137,7 @@ var serviceContext = (function () {
errMsg: 'getAudioState:ok', errMsg: 'getAudioState:ok',
duration: 1e3 * (audio.getDuration() || 0), duration: 1e3 * (audio.getDuration() || 0),
currentTime: audio.isStopped ? 0 : 1e3 * audio.getPosition(), currentTime: audio.isStopped ? 0 : 1e3 * audio.getPosition(),
paused: audio.isPaused, paused: audio.isPaused(),
src, src,
volume, volume,
startTime: 1e3 * startTime, startTime: 1e3 * startTime,
...@@ -3109,7 +3153,7 @@ var serviceContext = (function () { ...@@ -3109,7 +3153,7 @@ var serviceContext = (function () {
const audio = audios[audioId]; const audio = audios[audioId];
const operationTypes = ['play', 'pause', 'stop']; const operationTypes = ['play', 'pause', 'stop'];
if (operationTypes.indexOf(operationType) >= 0) { if (operationTypes.indexOf(operationType) >= 0) {
audio[operationType === operationTypes[0] && audio.isPaused ? 'resume' : operationType](); audio[operationType === operationTypes[0] && audio.isPaused() ? 'resume' : operationType]();
} else if (operationType === 'seek') { } else if (operationType === 'seek') {
audio.seekTo(currentTime / 1e3); audio.seekTo(currentTime / 1e3);
} }
...@@ -3118,9 +3162,9 @@ var serviceContext = (function () { ...@@ -3118,9 +3162,9 @@ var serviceContext = (function () {
} }
} }
let audio; let audio;
let timeUpdateTimer = null; let timeUpdateTimer = null;
const TIME_UPDATE = 250; const TIME_UPDATE = 250;
const publishBackgroundAudioStateChange = (state, res = {}) => publish('onBackgroundAudioStateChange', Object.assign({ const publishBackgroundAudioStateChange = (state, res = {}) => publish('onBackgroundAudioStateChange', Object.assign({
...@@ -3143,15 +3187,15 @@ var serviceContext = (function () { ...@@ -3143,15 +3187,15 @@ var serviceContext = (function () {
audio.addEventListener(event, () => { audio.addEventListener(event, () => {
// 添加 isStopped 属性是为了解决 安卓设备停止播放后获取播放进度不正确的问题 // 添加 isStopped 属性是为了解决 安卓设备停止播放后获取播放进度不正确的问题
if (event === 'play') { if (event === 'play') {
audio.isStopped = false; audio.isStopped = false;
startTimeUpdateTimer(); startTimeUpdateTimer();
} else if (event === 'stop') { } else if (event === 'stop') {
audio.isStopped = true; audio.isStopped = true;
} }
if (event === 'pause' || event === 'ended' || event === 'stop') { if (event === 'pause' || event === 'ended' || event === 'stop') {
stopTimeUpdateTimer(); stopTimeUpdateTimer();
} }
const eventName = `onMusic${event[0].toUpperCase() + event.substr(1)}`; const eventName = `onMusic${event[0].toUpperCase() + event.substr(1)}`;
publish(eventName, { publish(eventName, {
...@@ -3163,13 +3207,13 @@ var serviceContext = (function () { ...@@ -3163,13 +3207,13 @@ var serviceContext = (function () {
}); });
}); });
}); });
audio.addEventListener('waiting', () => { audio.addEventListener('waiting', () => {
stopTimeUpdateTimer(); stopTimeUpdateTimer();
publishBackgroundAudioStateChange('waiting', { publishBackgroundAudioStateChange('waiting', {
dataUrl: audio.src dataUrl: audio.src
}); });
}); });
audio.addEventListener('error', err => { audio.addEventListener('error', err => {
stopTimeUpdateTimer(); stopTimeUpdateTimer();
publish('onMusicError', { publish('onMusicError', {
dataUrl: audio.src, dataUrl: audio.src,
...@@ -3183,20 +3227,20 @@ var serviceContext = (function () { ...@@ -3183,20 +3227,20 @@ var serviceContext = (function () {
}); });
audio.addEventListener('prev', () => publish('onBackgroundAudioPrev')); audio.addEventListener('prev', () => publish('onBackgroundAudioPrev'));
audio.addEventListener('next', () => publish('onBackgroundAudioNext')); audio.addEventListener('next', () => publish('onBackgroundAudioNext'));
} }
function startTimeUpdateTimer () {
stopTimeUpdateTimer();
timeUpdateTimer = setInterval(() => {
publishBackgroundAudioStateChange('timeUpdate', {});
}, TIME_UPDATE);
}
function stopTimeUpdateTimer () { function startTimeUpdateTimer () {
if (timeUpdateTimer !== null) { stopTimeUpdateTimer();
clearInterval(timeUpdateTimer); timeUpdateTimer = setInterval(() => {
} publishBackgroundAudioStateChange('timeUpdate', {});
} }, TIME_UPDATE);
}
function stopTimeUpdateTimer () {
if (timeUpdateTimer !== null) {
clearInterval(timeUpdateTimer);
}
}
function setMusicState (args) { function setMusicState (args) {
initMusic(); initMusic();
...@@ -3225,7 +3269,7 @@ var serviceContext = (function () { ...@@ -3225,7 +3269,7 @@ var serviceContext = (function () {
dataUrl: audio.src, dataUrl: audio.src,
duration: audio.getDuration() || 0, duration: audio.getDuration() || 0,
currentPosition: audio.getPosition(), currentPosition: audio.getPosition(),
status: audio.isPaused ? 0 : 1, status: audio.isPaused() ? 0 : 1,
downloadPercent: Math.round(100 * audio.getBuffered() / audio.getDuration()), downloadPercent: Math.round(100 * audio.getBuffered() / audio.getDuration()),
errMsg: `getMusicPlayerState:ok` errMsg: `getMusicPlayerState:ok`
} }
...@@ -3301,7 +3345,7 @@ var serviceContext = (function () { ...@@ -3301,7 +3345,7 @@ var serviceContext = (function () {
let newData = { let newData = {
duration: audio.getDuration() || 0, duration: audio.getDuration() || 0,
currentTime: audio.isStopped ? 0 : audio.getPosition(), currentTime: audio.isStopped ? 0 : audio.getPosition(),
paused: audio.isPaused, paused: audio.isPaused(),
src: audio.src, src: audio.src,
buffered: audio.getBuffered(), buffered: audio.getBuffered(),
title: audio.title, title: audio.title,
...@@ -5651,14 +5695,21 @@ var serviceContext = (function () { ...@@ -5651,14 +5695,21 @@ var serviceContext = (function () {
openLocation: openLocation$1 openLocation: openLocation$1
}); });
function openLocation$2 (data) { function openLocation$2 (data, callbackId) {
showPage({ showPage({
url: '__uniappopenlocation', url: '__uniappopenlocation',
data, data,
style: { style: {
titleNView: { titleNView: {
type: 'transparent' type: 'transparent'
} },
popGesture: 'close',
backButtonAutoControl: 'close'
},
onClose () {
invoke$1(callbackId, {
errMsg: 'openLocation:fail cancel'
});
} }
}); });
return { return {
...@@ -9253,17 +9304,14 @@ var serviceContext = (function () { ...@@ -9253,17 +9304,14 @@ var serviceContext = (function () {
const eventNames = [ const eventNames = [
'load', 'load',
'close', 'close',
'verify',
'error' 'error'
]; ];
const ERROR_CODE_LIST = [-5001, -5002, -5003, -5004, -5005, -5006]; const ERROR_CODE_LIST = [-5001, -5002, -5003, -5004, -5005, -5006];
class RewardedVideoAd { class RewardedVideoAd {
constructor (adpid) { constructor (options = {}) {
this._options = {
adpid: adpid
};
const _callbacks = this._callbacks = {}; const _callbacks = this._callbacks = {};
eventNames.forEach(item => { eventNames.forEach(item => {
_callbacks[item] = []; _callbacks[item] = [];
...@@ -9277,7 +9325,7 @@ var serviceContext = (function () { ...@@ -9277,7 +9325,7 @@ var serviceContext = (function () {
this._adError = ''; this._adError = '';
this._loadPromiseResolve = null; this._loadPromiseResolve = null;
this._loadPromiseReject = null; this._loadPromiseReject = null;
const rewardAd = this._rewardAd = plus.ad.createRewardedVideoAd(this._options); const rewardAd = this._rewardAd = plus.ad.createRewardedVideoAd(options);
rewardAd.onLoad((e) => { rewardAd.onLoad((e) => {
this._isLoad = true; this._isLoad = true;
this._dispatchEvent('load', {}); this._dispatchEvent('load', {});
...@@ -9290,6 +9338,9 @@ var serviceContext = (function () { ...@@ -9290,6 +9338,9 @@ var serviceContext = (function () {
this._loadAd(); this._loadAd();
this._dispatchEvent('close', { isEnded: e.isEnded }); this._dispatchEvent('close', { isEnded: e.isEnded });
}); });
rewardAd.onVerify && rewardAd.onVerify((e) => {
this._dispatchEvent('verify', { isValid: e.isValid });
});
rewardAd.onError((e) => { rewardAd.onError((e) => {
const { code, message } = e; const { code, message } = e;
const data = { code: code, errMsg: message }; const data = { code: code, errMsg: message };
...@@ -9323,6 +9374,12 @@ var serviceContext = (function () { ...@@ -9323,6 +9374,12 @@ var serviceContext = (function () {
} }
}) })
} }
getProvider () {
return this._rewardAd.getProvider()
}
destroy () {
this._rewardAd.destroy();
}
_loadAd () { _loadAd () {
this._isLoad = false; this._isLoad = false;
this._rewardAd.load(); this._rewardAd.load();
...@@ -9336,10 +9393,8 @@ var serviceContext = (function () { ...@@ -9336,10 +9393,8 @@ var serviceContext = (function () {
} }
} }
function createRewardedVideoAd ({ function createRewardedVideoAd (options) {
adpid = '' return new RewardedVideoAd(options)
} = {}) {
return new RewardedVideoAd(adpid)
} }
...@@ -10646,8 +10701,9 @@ var serviceContext = (function () { ...@@ -10646,8 +10701,9 @@ var serviceContext = (function () {
var cId = canvasEventCallbacks.push(function (data) { var cId = canvasEventCallbacks.push(function (data) {
invoke$1(callbackId, data); invoke$1(callbackId, data);
}); });
// fix ...
operateCanvas(canvasId, pageId, 'putImageData', { operateCanvas(canvasId, pageId, 'putImageData', {
data: [...data], data: Array.prototype.slice.call(data),
x, x,
y, y,
width, width,
...@@ -10729,17 +10785,13 @@ var serviceContext = (function () { ...@@ -10729,17 +10785,13 @@ var serviceContext = (function () {
callback.invoke(callbackId, data); callback.invoke(callbackId, data);
}); });
const methods = ['getCenterLocation', 'getScale', 'getRegion', 'includePoints', 'translateMarker']; const methods = ['getCenterLocation', 'moveToLocation', 'getScale', 'getRegion', 'includePoints', 'translateMarker'];
class MapContext { class MapContext {
constructor (id, pageVm) { constructor (id, pageVm) {
this.id = id; this.id = id;
this.pageVm = pageVm; this.pageVm = pageVm;
} }
moveToLocation () {
operateMapPlayer$3(this.id, this.pageVm, 'moveToLocation');
}
} }
MapContext.prototype.$getAppMap = function () { MapContext.prototype.$getAppMap = function () {
...@@ -11058,11 +11110,11 @@ var serviceContext = (function () { ...@@ -11058,11 +11110,11 @@ var serviceContext = (function () {
}); });
const callbacks$a = { const callbacks$a = {
pause: [], pause: null,
resume: [], resume: null,
start: [], start: null,
stop: [], stop: null,
error: [] error: null
}; };
class RecorderManager { class RecorderManager {
...@@ -11071,15 +11123,13 @@ var serviceContext = (function () { ...@@ -11071,15 +11123,13 @@ var serviceContext = (function () {
const state = res.state; const state = res.state;
delete res.state; delete res.state;
delete res.errMsg; delete res.errMsg;
callbacks$a[state].forEach(callback => { if (typeof callbacks$a[state] === 'function') {
if (typeof callback === 'function') { callbacks$a[state](res);
callback(res); }
}
});
}); });
} }
onError (callback) { onError (callback) {
callbacks$a.error.push(callback); callbacks$a.error = callback;
} }
onFrameRecorded (callback) { onFrameRecorded (callback) {
...@@ -11091,16 +11141,16 @@ var serviceContext = (function () { ...@@ -11091,16 +11141,16 @@ var serviceContext = (function () {
} }
onPause (callback) { onPause (callback) {
callbacks$a.pause.push(callback); callbacks$a.pause = callback;
} }
onResume (callback) { onResume (callback) {
callbacks$a.resume.push(callback); callbacks$a.resume = callback;
} }
onStart (callback) { onStart (callback) {
callbacks$a.start.push(callback); callbacks$a.start = callback;
} }
onStop (callback) { onStop (callback) {
callbacks$a.stop.push(callback); callbacks$a.stop = callback;
} }
pause () { pause () {
invokeMethod('operateRecorder', { invokeMethod('operateRecorder', {
...@@ -11393,7 +11443,7 @@ var serviceContext = (function () { ...@@ -11393,7 +11443,7 @@ var serviceContext = (function () {
success, success,
fail, fail,
complete complete
}, errMsg) { } = {}, errMsg) {
var data = { var data = {
errMsg errMsg
}; };
...@@ -12146,7 +12196,7 @@ var serviceContext = (function () { ...@@ -12146,7 +12196,7 @@ var serviceContext = (function () {
return return
} }
if (!page.$page.meta.isNVue) { if (!page.$page.meta.isNVue) {
const target = page.$vm._$vd.elements.find(target => target.tagName === 'web-view' && target.events['message']); const target = page.$vm._$vd.elements.find(target => target.type === 'web-view' && target.events['message']);
if (!target) { if (!target) {
return return
} }
...@@ -12265,13 +12315,13 @@ var serviceContext = (function () { ...@@ -12265,13 +12315,13 @@ var serviceContext = (function () {
getCurrentPages getCurrentPages
}) { }) {
function createPageEvent (eventType) { function createPageEvent (eventType) {
return function (args, pageId) { return function (args, pageId) {
pageId = parseInt(pageId); pageId = parseInt(pageId);
const pages = getCurrentPages(); const pages = getCurrentPages();
const page = pages.find(page => page.$page.id === pageId); const page = pages.find(page => page.$page.id === pageId);
if (page) { if (page) {
callPageHook(page, eventType, args); callPageHook(page, eventType, args);
} else { } else if (process.env.NODE_ENV !== 'production') {
console.error(`Not Found:Page[${pageId}]`); console.error(`Not Found:Page[${pageId}]`);
} }
} }
...@@ -12304,7 +12354,7 @@ var serviceContext = (function () { ...@@ -12304,7 +12354,7 @@ var serviceContext = (function () {
} }
callback(res); callback(res);
} }
} }
subscribe('onPageScroll', createPageEvent('onPageScroll')); subscribe('onPageScroll', createPageEvent('onPageScroll'));
subscribe('onReachBottom', createPageEvent('onReachBottom')); subscribe('onReachBottom', createPageEvent('onReachBottom'));
...@@ -13150,61 +13200,13 @@ var serviceContext = (function () { ...@@ -13150,61 +13200,13 @@ var serviceContext = (function () {
data[k] = v; data[k] = v;
} }
function diffObject (newObj, oldObj, every = true) {
let result, key, cur, old;
for (key in newObj) {
cur = newObj[key];
old = oldObj[key];
if (old !== cur) {
if (!every) {
return newObj
}
setResult(result || (result = Object.create(null)), key, cur);
}
}
return result
}
function diffArray (newArr, oldArr) {
const newLen = newArr.length;
if (newLen !== oldArr.length) {
return newArr
}
if (isPlainObject(newArr[0])) {
for (let i = 0; i < newLen; i++) {
if (diffObject(newArr[i], oldArr[i], false)) {
return newArr
}
}
} else {
for (let i = 0; i < newLen; i++) {
if (newArr[i] !== oldArr[i]) {
return newArr
}
}
}
}
function diffElmData (newObj, oldObj) { function diffElmData (newObj, oldObj) {
let result, key, cur, old; let result, key, cur, old;
for (key in newObj) { for (key in newObj) {
cur = newObj[key]; cur = newObj[key];
old = oldObj[key]; old = oldObj[key];
if (old !== cur) { if (!looseEqual(old, cur)) {
// 全量同步 style (因为 style 可能会动态删除部分样式) setResult(result || (result = Object.create(null)), key, cur);
if (key === B_STYLE && isPlainObject(cur) && isPlainObject(old)) {
if (Object.keys(cur).length !== Object.keys(old).length) { // 长度不等
setResult(result || (result = Object.create(null)), B_STYLE, cur);
} else {
const style = diffObject(cur, old, false);
style && setResult(result || (result = Object.create(null)), B_STYLE, style);
}
} else if (key === V_FOR && Array.isArray(cur) && Array.isArray(old)) {
const vFor = diffArray(cur, old);
vFor && setResult(result || (result = Object.create(null)), V_FOR, vFor);
} else {
setResult(result || (result = Object.create(null)), key, cur);
}
} }
} }
return result return result
......
import { import {
isPlainObject looseEqual
} from 'uni-shared' } from 'uni-shared'
import {
V_FOR,
B_STYLE
} from '../../constants'
function setResult (data, k, v) { function setResult (data, k, v) {
data[k] = v data[k] = v
} }
function diffObject (newObj, oldObj, every = true) {
let result, key, cur, old
for (key in newObj) {
cur = newObj[key]
old = oldObj[key]
if (old !== cur) {
if (!every) {
return newObj
}
setResult(result || (result = Object.create(null)), key, cur)
}
}
return result
}
function diffArray (newArr, oldArr) {
const newLen = newArr.length
if (newLen !== oldArr.length) {
return newArr
}
if (isPlainObject(newArr[0])) {
for (let i = 0; i < newLen; i++) {
if (diffObject(newArr[i], oldArr[i], false)) {
return newArr
}
}
} else {
for (let i = 0; i < newLen; i++) {
if (newArr[i] !== oldArr[i]) {
return newArr
}
}
}
}
function diffElmData (newObj, oldObj) { function diffElmData (newObj, oldObj) {
let result, key, cur, old let result, key, cur, old
for (key in newObj) { for (key in newObj) {
cur = newObj[key] cur = newObj[key]
old = oldObj[key] old = oldObj[key]
if (old !== cur) { if (!looseEqual(old, cur)) {
if (key === B_STYLE && isPlainObject(cur) && isPlainObject(old)) { // 全量同步 style (因为 style 可能会动态删除部分样式) setResult(result || (result = Object.create(null)), key, cur)
if (Object.keys(cur).length !== Object.keys(old).length) { // 长度不等
setResult(result || (result = Object.create(null)), B_STYLE, cur)
} else {
const style = diffObject(cur, old, false)
style && setResult(result || (result = Object.create(null)), B_STYLE, style)
}
} else if (key === V_FOR && Array.isArray(cur) && Array.isArray(old)) {
const vFor = diffArray(cur, old)
vFor && setResult(result || (result = Object.create(null)), V_FOR, vFor)
} else {
if (key.indexOf('change:') === 0) { // wxs change:prop
try {
// 先简单的用 stringify 判断
if (JSON.stringify(cur) === JSON.stringify(old)) {
continue
}
} catch (e) {}
}
setResult(result || (result = Object.create(null)), key, cur)
}
} }
} }
return result return result
......
...@@ -96,3 +96,42 @@ export function debounce (fn, delay) { ...@@ -96,3 +96,42 @@ export function debounce (fn, delay) {
export function kebabCase (string) { export function kebabCase (string) {
return string.replace(/[A-Z]/g, str => '-' + str.toLowerCase()) return string.replace(/[A-Z]/g, str => '-' + str.toLowerCase())
} }
/**
* Check if two values are loosely equal - that is,
* if they are plain objects, do they have the same shape?
*/
export function looseEqual (a, b) {
if (a === b) return true
const isObjectA = isObject(a)
const isObjectB = isObject(b)
if (isObjectA && isObjectB) {
try {
const isArrayA = Array.isArray(a)
const isArrayB = Array.isArray(b)
if (isArrayA && isArrayB) {
return a.length === b.length && a.every((e, i) => {
return looseEqual(e, b[i])
})
} else if (a instanceof Date && b instanceof Date) {
return a.getTime() === b.getTime()
} else if (!isArrayA && !isArrayB) {
const keysA = Object.keys(a)
const keysB = Object.keys(b)
return keysA.length === keysB.length && keysA.every(key => {
return looseEqual(a[key], b[key])
})
} else {
/* istanbul ignore next */
return false
}
} catch (e) {
/* istanbul ignore next */
return false
}
} else if (!isObjectA && !isObjectB) {
return String(a) === String(b)
} else {
return false
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册