事实证明,扩展具有挑战性,因为我正在尝试操纵参数对象。
我当前的扩展函数在初始给定对象之后不考虑多个参数
_.extend = function(object, sources) {
return _.reduce(sources, function(memo, current) {
memo[Object.keys(sources)] = current || 0;
return memo;
}, object)
}
首先,我尝试复制参数对象,将其转换为数组,然后将第一个参数移出。这是非常不优雅的,但仍然被证明是无效的
我意识到 apply() 或 call() 应该在这种情况下以某种方式使用。当我尝试时,它也不起作用。
_.extend = function(object) {
var copy = [].slice.call(arguments);
copy.shift();
doIT.apply(this, copy);
var doIt = function(copy) {
return _.reduce(copy, function(memo, current) {
memo[Object.keys(copy)] = current || 0;
return memo;
}, object)
}
doIt(copy);
}
有什么想法可以解决这个问题吗?
最佳答案
无需在函数上使用apply
,只需正常调用即可。通过这样做,您可以将移位后的数组作为参数列表传递到函数中。由于您仅在参数列表中使用 copy
,因此只有一个参数可以实现。也不需要 call
,因为不需要 this
上下文,您可以轻松调用该函数。最后,由于您的函数不是函数声明,因此在对保存该函数的表达式求值之前,它不可用(在 var doIt
之后可用)。
现在,您的 doIt
函数做错了什么:
memo[Object.keys(copy)] = current || 0;
Object.keys(copy)
返回一个带有副本 keys
的数组。所以你正在做:
memo[array] = current || 0;
array
将被转换为字符串,但这绝对不是您想要的。您需要的是迭代 copy
数组的每个元素属性(每个元素属性都在 current
上)并将这些属性复制到您的第一个对象中(memo
累加器)。像这样:
var extend = function (object) {
var copy = [].slice.call(arguments);
copy.shift();
var doIt = function (copy) {
return copy.reduce(function (memo, current) {
Object.keys(current).forEach(function (key) {
memo[key] = current[key];
});
return memo;
}, object)
}
return doIt(copy);
}
但是,扩展仍然需要处理适当的 getter 和 setter。因此,您需要执行以下操作:
var extend = function (object) {
var copy = [].slice.call(arguments);
copy.shift();
var doIt = function (copy) {
return copy.reduce(function (memo, current) {
Object.keys(current).forEach(function (key) {
var pDesc = Object.getOwnPropertyDescriptor(current, key);
Object.defineProperty(memo, key, pDesc);
});
return memo;
}, object)
}
return doIt(copy);
}
关于javascript - 从头开始编码 JS Underscore _.extend,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32974282/