我有一个类型为ServiceWorkerRegistration
的对象,我想对其进行字符串化:
const reg = await navigator.serviceWorker.register(`https://www.myurl.com/Worker.js`, {scope:"/"});
当我执行console.log(reg)
时,我得到以下结果:
ServiceWorkerRegistration { installing: null, waiting: null, active: ServiceWorker, navigationPreload: NavigationPreloadManager, scope: "https://www.myurl.com/", updateViaCache: "imports", onupdatefound: null, pushManager: PushManager }
active: ServiceWorker { scriptURL: "https://www.myurl.com/Worker.js", state: "activated", onstatechange: null, … }
onerror: null
onstatechange: null
scriptURL: "https://www.myurl.com/Worker.js"
state: "activated"
<prototype>: ServiceWorkerPrototype { postMessage: postMessage(), scriptURL: Getter, state: Getter, … }
installing: null
navigationPreload: NavigationPreloadManager { }
onupdatefound: null
pushManager: PushManager { }
scope: "https://www.myurl.com/"
updateViaCache: "imports"
waiting: null
<prototype>: ServiceWorkerRegistrationPrototype { update: update(), unregister: unregister(), showNotification: showNotification(), … }
当我做typeof reg
时,我得到'object'
然而,如果我尝试JSON.stringify(reg)
,我得到{}
。同样,如果我尝试执行Object.keys(reg)
,我得到[]
。
我看了答案,如为什么JSON。Stringify返回空对象符号"{}"对于一个看起来有属性的物体?和为什么JSON。stringify on TypeError返回一个空对象,并声明当对象没有可枚举属性时发生此错误。
一个创可贴的解决方案是我手动打印每个字段,例如console.log(reg["installing"]);
,或者手动重置每个属性为可枚举的,例如Object.defineProperty(reg, 'installing', {enumerable: true})
。
然而,我希望能够做这样的事情:
Object.keys(reg).forEach(key=>console.log(reg[key]));
要做到这一点,对象必须具有可枚举的属性。如何使属性可枚举?从评论我的工作解决方案是只是复制对象(解决方案在TS):
const objCpy = (obj : any) : string =>{
let newObj : any = {}
const keys : string[] = Object.keys(Object.getPrototypeOf(obj));
keys.forEach((key : string)=>{
let val : any = obj[key]
if(typeof val === "object" && val !== null){
val = objCpy(val)
}
newObj[key] = val;
})
return newObj;
}
然后按预期进行字符串化:
JSON.stringify(objCpy(reg))
>> `{"installing":{"scriptURL":"http://localhost:3001/Worker.js","state":"installing","onstatechange":null,"onerror":null},"waiting":null,"active":null,"navigationPreload":{},"scope":"http://localhost:3001/","updateViaCache":"imports","onupdatefound":null,"pushManager":{}}`