Reputation: 1477
Extend has proven challenging because I'm trying to manipulate the arguments object.
My current extend function does not account for more than one argument after the initial given object
_.extend = function(object, sources) {
return _.reduce(sources, function(memo, current) {
memo[Object.keys(sources)] = current || 0;
return memo;
}, object)
}
At first, I tried to make a copy of the arguments object, turn it into an array, and shift() the first argument out. This is terribly inelegant, but has still proven to be ineffective
I realized that apply() or call() should be used in this context somehow. When I tried it, it also didn't work.
_.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);
}
Any ideas on what I can do to fix this?
Upvotes: 0
Views: 500
Reputation: 14423
There's no need to use apply
on your function, just call it normally. By doing so, you are passing your shifted array as a list of arguments into your function. Since you are only working with copy
in your parameter list then only one argument would make it. There's no need for call
either, as you can easily invoke the function since no this
context is required. Lastly, since your function is not a function declaration, it won't be available until the expression holding the function has been evaluated (available after var doIt
).
Now, your doIt
function is doing something wrong:
memo[Object.keys(copy)] = current || 0;
Object.keys(copy)
returns an array with copy keys
. So you are doing:
memo[array] = current || 0;
The array
will be casted to a string, but it's definitely not something you want either. What you need to is iterate each element properties of the copy
array (each on is on current
) and copy those properties into your first object (memo
accumulator). Like this:
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);
}
However, extends still need to handle the appropriated getters and setters. So you'll need to do something like:
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);
}
Upvotes: 1