_.memoize = function(func) {
var cached = {};
return function() {
var args = Array.prototype.slice.call(arguments);
if (cached[args]) {
console.log('returning cached');
return cached[args];
} else {
cached[args] = func.apply(this, args);
return cached[args];
}
};
};
_.memoize = function(func) {
var cached = {};
return function() {
if (cached[arguments]) {
console.log('returning cached');
return cached[arguments];
} else {
cached[arguments] = func.apply(this, arguments);
return cached[arguments];
}
};
};
var add = function(a, b) {
return a + b;
};
var memoAdd = _.memoize(add);
memoAdd(1, 2) => 3;
memoAdd(3, 4)
'returning cached'
=> 3; ????
为什么没有Array.prototype.slice.call,第二个memoize实现不起作用?
是括号实际上将字参数字串化为键而不是实际的真实参数吗?
答案 0 :(得分:1)
是括号实际上将字参数字串化为键而不是实际的真实参数吗?
关闭,但不完全。你是否正确,涉及到字符串化的差异。 arguments
,您可能知道或不知道,不是数组,它是一个特殊的Arguments object。由于一些原因,这是不方便的,但这里可以说明与此相关的那个:
function argsObj() {
var obj = {};
var args = Array.prototype.slice.call(arguments);
obj[arguments] = 1;
obj[args] = 2;
return obj;
}
console.log(argsObj(123, 456, 789));
// => { "[object Arguments]": 1,
// "123,456,789": 2
// }
当Arguments对象被“字符串化”以用作属性名称时,我们始终得到[object Arguments]
。如果我们希望属性名实际反映参数本身 - 我们需要进行memoization - 我们必须首先将Arguments对象转换为数组,这是Array.prototype.slice.call(arguments)
所做的。
P.S。即使使用Array.prototype.slice
这个备忘录方案也有很大的弱点。看看当你使用对象甚至数组的参数进行尝试时会发生什么。
答案 1 :(得分:0)
arguments 是对象,而不是数组。
arguments对象不是Array。它类似于Array,但除了length之外没有任何Array属性。
因此,当您使用第二个实现运行memoization时,您会在cached
变量中看到这一点:
Cached = {} //Empty cache
(index):56 Arguments = [object Arguments] //Arguments is an object
(index):57 Is Array = false //Not an array
(index):74 3
//Will set the object as key, not an array
(index):55 Cached = {"[object Arguments]":3}
(index):56 Arguments = [object Arguments]
(index):57 Is Array = false
//because it will still access to cached[[object ...]]
(index):59 returning cached
(index):76 3
由于[object Arguments]
,它始终会设置和访问密钥stringification
。
因此,您必须使用第一个实现,使用 Array.prototype.slice.call ,它将转换为真实数组。
然后,在字符串化后,您将获得:
Cached = {}
(index):39 Arguments = 1,2 //Is an array as you can see
(index):40 Is Array = true
(index):74 3
//Set an array as key
(index):38 Cached = {"1,2":3}
//Key 3,4 is not in the cached variable, you can continue
(index):39 Arguments = 3,4
(index):40 Is Array = true
(index):76 7