JavaScriptMap对象上的MDN文档提供了有用的信息,但似乎忽略了一些重要的点。也许它们对大多数人来说是显而易见的,但我不清楚为什么它会这样工作,我希望能澄清。
键(如果不是字符串(似乎是对包括函数对象在内的对象的引用。而且,除了函数对象之外,对象的值似乎也是对对象的引用。因此,在下面的代码中,mapF.get(updateFunc).b = 25
更新映射中保持的对象,而不是mapF.get()
仅返回对象的副本。
但是,当值是函数对象时,这似乎不适用于这种情况,而是似乎复制了函数,因此在更新函数funcInMap
后,mapF.get('funcInMap')(4)
返回8
而不是12
;并且因此看起来持有CCD_ 7的原始定义的副本。
我是在犯错误,还是这是它的工作方式和应该期望的工作方式?非常感谢。
var funcInMap = function (x) {
return x * 2;
};
function updateFunc() {
funcInMap = function (x) { return x * 3; };
}
var mapF = new Map();
mapF.set(updateFunc, {a: 5, b: 10});
mapF.set('funcInMap',funcInMap);
console.log("b pre map update: " + mapF.get(updateFunc).b); // 10
mapF.get(updateFunc).b = 25;
console.log("b post map update: " + mapF.get(updateFunc).b); // 25
console.log(mapF.get(updateFunc));
console.log("funcInMap pre update : " + mapF.get('funcInMap')(4)); // 8
updateFunc();
console.log("funcInMap post update : " + funcInMap(4)); // 12
console.log("mapF funcInMap post update : " + mapF.get('funcInMap')(4)); // 8
收到答案后添加。
function updateFunc() { }
var mapF = new Map(),
obj = {a: 5, b: 10};
mapF.set(updateFunc, obj);
console.log("Original obj: " + Object.values(mapF.get(updateFunc)));
// Return 5, 10
obj = {a: 105, b: 110};
console.log("Updated obj: " + Object.values(mapF.get(updateFunc)));
// Return 5, 10
/*
I would've been stupid to expect the second group to return
105, 110; but that is what I was expecting when the objects
were functions.
*/
在将我的一些项目代码更改为使用映射而不是常规对象之后,我突然想到,在将map
key
设置为具有value
即object
时,我又有点愚蠢了。也许在某些情况下,这是有道理的;但是,如果目标是以类似于向DOM元素或函数添加属性但在未来永远不会发生冲突的方式将一些数据与DOM元素或功能关联起来,那么重点不是在map
中添加map
吗?
因此,上面mapF.set(updateFunc, {a: 5, b: 10})
的代码示例应该是mapF.set(updateFunc, new Map( [ ['a', 5], ['b', 10] ] ) )
,并且可以使用mapF.get(updateFunc).set('c', 20)
添加属性(等等(。
但是,如果不使用两次get
,就不能使用内部map
。因此,看起来null object
无论如何都将更容易被编码。
function myFunc() { };
var map_map = new Map([ [myFunc, new Map([ ['a',10], ['b',20]]) ] ] );
var obj = Object.create(null, {
a: { value: 10, enumerable: true },
b: { value: 20, enumerable: true }
});
var map_obj = new Map([[myFunc, obj]]);
console.log( map_map.get(myFunc).get('a') ); //=> 10
console.log( map_map.get(myFunc)['a'] ); //=> undefined
console.log( map_obj.get(myFunc).a); // => 10
当您在JS:中编写时
var funcInMap = function (x) { return x * 2; };
JS解释器创建了两个东西:
-1-对应于function (x) { return x * 2; }
的汇编代码,它将其放置在存储器地址@_memoryAddress_x1
-2-创建funcInMap
变量,将内存地址@_memoryAddress_x1
附加到该变量
随后您编码:
mapF.set('funcInMap',funcInMap);
JS解释器";变换";到mapF.set('funcInMap', @_memoryAddress_x1);
,因为@_memoryAddress_x1
与funcInMap
变量的内容匹配
在updateFunc()
中执行类似的操作:它为function (x) { return x * 3; }
创建汇编代码,地址为@_memoryAddress_ZZ
并将funcInMap
的值替换为@_memoryAddress_ZZ
但是地址CCD_ 32仍然存在
及其用于执行的汇编代码。
在类似的逻辑中(无需使用映射对象(
let
function_A = () => 'a'
, function_B = () => 'b'
, function_C = function_A
;
console.log( function_A() ) // return 'a'
console.log( function_C() ) // return 'a'
function_A = function_B
console.log( function_A() ) // return 'b'
console.log( function_C() ) // return 'a'