如何迭代弱图?

时间:2015-09-04 16:38:37

标签: javascript garbage-collection iterator weakmap

javascript WeakMap(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap)不允许您按设计获取密钥或长度或大小。

是否有可能以某种方式循环条目?

如果没有.. Chrome控制台如何执行此操作?

enter image description here

3 个答案:

答案 0 :(得分:18)

  

是否有可能以某种方式循环条目?

不,正如您所说,WeakMap的内容无法通过设计访问,并且没有可迭代性。

  

如果不是...... Chrome控制台如何执行此操作?

控制台使用JS引擎的调试API,它允许访问对象的内部(也包括承诺状态,包装的基元等)等等。

答案 1 :(得分:1)

事情正在发生变化,由于参考文献薄弱,很快将有可能创建可迭代的星期地图。 请参阅tc39弱引用提案中的iterable WeakMap example

(请注意,使用--harmony-weak-refs标志的nodejs v12。?。?已经可以实现)

答案 2 :(得分:0)

在您的(2015)问题中使用限定词跑得很远,特别是:

<块引用>

仍然可以以某种方式循环条目吗?

是的。

在一种荒谬的情况下,可以模拟然后迭代 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));
    }
  }
}

它有点丑,很脆弱,而且只能解决荒谬的边缘情况;不客气!