@antmove/wx-alipay
Version:
transform wechat miniprogram to alipay miniprogram tool.
183 lines (160 loc) • 3.82 kB
JavaScript
const toString = Object.prototype.toString
function __type(x) {
// fix typeof null = object
if (x === null) {
return 'null'
}
const t = typeof x
if (t !== 'object') {
return t
}
let cls
let clsLow
try {
cls = toString.call(x).slice(8, -1)
clsLow = cls.toLowerCase()
} catch (e) {
// ie下的 activex对象
return 'object'
}
if (clsLow !== 'object') {
return clsLow
}
if (x.constructor === Object) {
return clsLow
}
// Object.create(null)
try {
/* eslint-disable no-proto */
if (Object.getPrototypeOf(x) === null || x.__proto__ === null) {
/* eslint-enable no-proto */
return 'object'
}
} catch (e) {
//
}
try {
const cname = x.constructor.name
if (typeof cname === 'string') {
return cname
}
} catch (e) {
// 无constructor
}
// function A() {}; A.prototype.constructor = null; new A
return 'unknown'
}
function SimpleWeakmap() {
this.cacheArray = []
}
const UNIQUE_KEY = `com.yanhaijing.jsmini.clone${(new Date()).getTime()}`
SimpleWeakmap.prototype.set = function(key, value) {
this.cacheArray.push(key)
key[UNIQUE_KEY] = value
}
SimpleWeakmap.prototype.get = function(key) {
return key[UNIQUE_KEY]
}
SimpleWeakmap.prototype.clear = function() {
for (let i = 0; i < this.cacheArray.length; i++) {
const key = this.cacheArray[i]
delete key[UNIQUE_KEY]
}
this.cacheArray.length = 0
}
function getWeakMap() {
let result
if (typeof WeakMap !== 'undefined' && __type(WeakMap) === 'function') {
result = new WeakMap()
if (__type(result) === 'weakmap') {
return result
}
}
result = new SimpleWeakmap()
return result
}
function isClone(x) {
const t = __type(x)
return t === 'object' || t === 'array'
}
function hasOwnProp(obj, key) {
return Object.prototype.hasOwnProperty.call(obj, key)
}
function copy(x) {
const uniqueData = getWeakMap()
const t = __type(x)
let root = x
if (t === 'array') {
root = []
} else if (t === 'object') {
root = {}
}
// 循环数组
const loopList = [
{
parent: root,
key: undefined,
data: x,
}
]
while (loopList.length) {
// 深度优先
const node = loopList.pop()
const parent = node.parent
const key = node.key
const source = node.data
const tt = __type(source)
// 初始化赋值目标,key为undefined则拷贝到父元素,否则拷贝到子元素
let target = parent
if (typeof key !== 'undefined') {
parent[key] = tt === 'array' ? [] : {}
target = parent[key]
}
// 复杂数据需要缓存操作
if (isClone(source)) {
// 命中缓存,直接返回缓存数据
const uniqueTarget = uniqueData.get(source)
if (uniqueTarget) {
parent[key] = uniqueTarget
continue // 中断本次循环
}
// 未命中缓存,保存到缓存
uniqueData.set(source, target)
}
if (tt === 'array') {
for (let i = 0; i < source.length; i++) {
if (isClone(source[i])) {
// 下一次循环
loopList.push({
parent: target,
key: i,
data: source[i],
})
} else {
target[i] = source[i]
}
}
} else if (tt === 'object') {
for (const k in source) {
if (hasOwnProp(source, k)) {
if (k === UNIQUE_KEY) { continue }
if (isClone(source[k])) {
// 下一次循环
loopList.push({
parent: target,
key: k,
data: source[k],
})
} else {
target[k] = source[k]
}
}
}
}
}
uniqueData.clear && uniqueData.clear()
return root
}
module.exports = {
copy,
}