28

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

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

如果不是 .. Chrome 控制台如何做到这一点?

在此处输入图像描述

4

3 回答 3

35

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

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

如果不是……Chrome 控制台是如何做到这一点的?

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

于 2015-09-12T20:05:31.267 回答
5

事情正在发生变化,由于参考薄弱,很快就有可能创建可迭代的周图。请参阅tc39 weakrefs 提案中的可迭代 WeakMap 示例。

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

于 2019-11-14T20:36:07.417 回答
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));
    }
  }
}

它有点难看,很脆弱,而且只能解决一个荒谬的边缘情况;别客气!

于 2021-06-20T00:50:49.963 回答