如何迭代弱图?
How to iterate over a weakmap?
A javascript WeakMap ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap ) 不允许您通过设计获得密钥、长度或大小。
是否有可能以某种方式循环访问条目?
如果不是 .. Chrome 控制台是如何做到这一点的?
Is it possible to nevertheless loop over entries in some way?
不,正如你所说,WeakMap
的内容是设计上不可访问的,也没有可迭代性。
If not … how does the Chrome console do this?
控制台使用 JS 引擎的调试 API,它允许访问对象的内部结构(也可以承诺状态、包装原语等)等等。
事情正在发生变化,由于引用较弱,很快就可以创建可迭代的周图。
请参阅 tc39 weakrefs 提案中的 iterable WeakMap example。
(请注意,nodejs v12.?.? 使用 --harmony-weak-refs
标志已经可行)
运行 在你的 (2015) 问题中有一个限定词,具体来说:
Is it possible to nevertheless loop over entries in some way ?
是的。
在一种荒谬的情况下,可以模拟然后迭代 WeakMap 的键和值,还可以制作 WeakMap 的适当、独立的副本。
如果您希望克隆的 WeakMap 是由构造函数以非常特定的方式构建的,您可以这样做:
// Define a Constructor-Function
// that makes objects
// containing WeakMaps:
function makeWeakMapObject(){
this.wm1 = new WeakMap();
this.o1 = {};
this.o2 = {"orange":"orange"};
this.wm1.set(this.o1, 37);
this.wm1.set(this.o2, 'azerty');
}
// Construct a new object:
let constructedWeakMapObject = new makeWeakMapObject();
// Then set a new key-value pair
// on the WeakMap in your object;
// because, ya know, otherwise you'd
// just reuse the WeakMap constructor
// and wouldn't need to clone :D
constructedWeakMapObject.added = {"ya":"glad"};
constructedWeakMapObject.wm1.set(constructedWeakMapObject.added, 42);
// In preparation to clone your newly constructed object,
// get that newly constructed object's property descriptors:
let props = Object.getOwnPropertyDescriptors(constructedWeakMapObject);
// Have a gander at those props; just for fun:
console.log({"props":props});
// Attempt to clone the constructedWeakMapObject
// using its ownPropertyDescriptors
let weakClone = new cloneWeak(props);
// and then check out what you made:
console.log({"weakClone":weakClone});
// Verify that you've made an independent clone
// (even though this example is shallow)
// by altering the WeakMap in your weakClone:
weakClone.wm.delete(weakClone.o1);
// Make sure your clone was altered:
console.log(weakClone.wm.get(weakClone.o1));
// And then check to see that the
// changes to your clone
// don't appear on your constructed object:
console.log(constructedWeakMapObject);
console.log(constructedWeakMapObject.wm1.get(constructedWeakMapObject.o1));
// A support function to help you use fresh keys in your cloned WeakMap to keep it independent from your original WeakMap
function cloneObject(obj) { // use something more robust, like underscore: _.cloneDeep(obj); actually, you'll likely have to roll your own so you can make clones of functions... anywho
var clone = {};
for(var i in obj) {
if(typeof(obj[i])==="object" && obj[i] !== null)
clone[i] = cloneObject(obj[i]);
else
clone[i] = obj[i];
}
return clone;
}
// Called as a constructor function w/arguments
function cloneWeak(inco){ // a bit wonky, at least in the middle
this.wm = new WeakMap();
let tempMap;
for(key in inco){
// Build keys on 'this' that match the incoming keys
if(Object.prototype.toString.call(inco[key].value) !== "[object WeakMap]"){
this[key] = cloneObject(inco[key].value);
}
// Reference the incoming map from your temp map
// (this makes the following loop possible)
else{tempMap = inco[key].value;}
}
this.fakeForHack = {}; // no idea why this works
this.wm.set(this.fakeForHack, "ok"); // no idea why this works... without it, the WeakMap entry for made.wm1.get(made.added) won't transfer -> ???
for(key in inco){
if(Object.prototype.toString.call(inco[key].value) !== "[object WeakMap]"){
// Set values for 'this' WeakMap:
this.wm.set(this[key], tempMap.get(inco[key].value));
}
}
}
它有点丑,它很脆弱,而且它只解决了一个荒谬的边缘情况;不客气!
A javascript WeakMap ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap ) 不允许您通过设计获得密钥、长度或大小。
是否有可能以某种方式循环访问条目?
如果不是 .. Chrome 控制台是如何做到这一点的?
Is it possible to nevertheless loop over entries in some way?
不,正如你所说,WeakMap
的内容是设计上不可访问的,也没有可迭代性。
If not … how does the Chrome console do this?
控制台使用 JS 引擎的调试 API,它允许访问对象的内部结构(也可以承诺状态、包装原语等)等等。
事情正在发生变化,由于引用较弱,很快就可以创建可迭代的周图。 请参阅 tc39 weakrefs 提案中的 iterable WeakMap example。
(请注意,nodejs v12.?.? 使用 --harmony-weak-refs
标志已经可行)
运行 在你的 (2015) 问题中有一个限定词,具体来说:
Is it possible to nevertheless loop over entries in some way ?
是的。
在一种荒谬的情况下,可以模拟然后迭代 WeakMap 的键和值,还可以制作 WeakMap 的适当、独立的副本。
如果您希望克隆的 WeakMap 是由构造函数以非常特定的方式构建的,您可以这样做:
// Define a Constructor-Function
// that makes objects
// containing WeakMaps:
function makeWeakMapObject(){
this.wm1 = new WeakMap();
this.o1 = {};
this.o2 = {"orange":"orange"};
this.wm1.set(this.o1, 37);
this.wm1.set(this.o2, 'azerty');
}
// Construct a new object:
let constructedWeakMapObject = new makeWeakMapObject();
// Then set a new key-value pair
// on the WeakMap in your object;
// because, ya know, otherwise you'd
// just reuse the WeakMap constructor
// and wouldn't need to clone :D
constructedWeakMapObject.added = {"ya":"glad"};
constructedWeakMapObject.wm1.set(constructedWeakMapObject.added, 42);
// In preparation to clone your newly constructed object,
// get that newly constructed object's property descriptors:
let props = Object.getOwnPropertyDescriptors(constructedWeakMapObject);
// Have a gander at those props; just for fun:
console.log({"props":props});
// Attempt to clone the constructedWeakMapObject
// using its ownPropertyDescriptors
let weakClone = new cloneWeak(props);
// and then check out what you made:
console.log({"weakClone":weakClone});
// Verify that you've made an independent clone
// (even though this example is shallow)
// by altering the WeakMap in your weakClone:
weakClone.wm.delete(weakClone.o1);
// Make sure your clone was altered:
console.log(weakClone.wm.get(weakClone.o1));
// And then check to see that the
// changes to your clone
// don't appear on your constructed object:
console.log(constructedWeakMapObject);
console.log(constructedWeakMapObject.wm1.get(constructedWeakMapObject.o1));
// A support function to help you use fresh keys in your cloned WeakMap to keep it independent from your original WeakMap
function cloneObject(obj) { // use something more robust, like underscore: _.cloneDeep(obj); actually, you'll likely have to roll your own so you can make clones of functions... anywho
var clone = {};
for(var i in obj) {
if(typeof(obj[i])==="object" && obj[i] !== null)
clone[i] = cloneObject(obj[i]);
else
clone[i] = obj[i];
}
return clone;
}
// Called as a constructor function w/arguments
function cloneWeak(inco){ // a bit wonky, at least in the middle
this.wm = new WeakMap();
let tempMap;
for(key in inco){
// Build keys on 'this' that match the incoming keys
if(Object.prototype.toString.call(inco[key].value) !== "[object WeakMap]"){
this[key] = cloneObject(inco[key].value);
}
// Reference the incoming map from your temp map
// (this makes the following loop possible)
else{tempMap = inco[key].value;}
}
this.fakeForHack = {}; // no idea why this works
this.wm.set(this.fakeForHack, "ok"); // no idea why this works... without it, the WeakMap entry for made.wm1.get(made.added) won't transfer -> ???
for(key in inco){
if(Object.prototype.toString.call(inco[key].value) !== "[object WeakMap]"){
// Set values for 'this' WeakMap:
this.wm.set(this[key], tempMap.get(inco[key].value));
}
}
}
它有点丑,它很脆弱,而且它只解决了一个荒谬的边缘情况;不客气!