问题
The following code:
let resultsArray = Array.apply(null, Array(10)).map(Number.prototype.valueOf,0);
creates the following array
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Why does map() need Number.prototype.valueOf
just to push the number 0 in to each position of this array. Is there a different (more efficient) way to achieve this result, or is this the best way?
回答1:
If you read the map documentation you can read this:
The map() method creates a new array with the results of calling a provided function on every element in this array.
So you need to use the function Number.prototype.valueOf in first parameter and a Number object in second optional parameter to fill the new array. The Number object is used as the this of the first parameter.
You can also write this for the same result:
let resultsArray = Array.apply(null, Array(10)).map(function(){return 0;});
But if you juste want to fill an array with a value, I think you may use the Array.prototype.fill method.
The fill() method fills all the elements of an array from a start index to an end index with a static value.
let resultsArray = (new Array(10)).fill(0);
Performance test:
var start, stop, array;
var iteration = 100000;
// Map
start = Date.now();
array = Array.apply(null, Array(iteration)).map(Number.prototype.valueOf,0);
stop = Date.now();
console.log("Map executed in "+(stop-start)+"ms");
// Map simple array
start = Date.now();
array = (new Array(iteration)).map(Number.prototype.valueOf,0);
stop = Date.now();
console.log("Map simple array executed in "+(stop-start)+"ms");
// Map simple function
start = Date.now();
array = (new Array(iteration)).map(function(){return 0;});
stop = Date.now();
console.log("Map simple function executed in "+(stop-start)+"ms");
// Array.from - ES6 from @Zohaib ijaz
start = Date.now();
array = Array.from(new Array(iteration), () => 0)
stop = Date.now();
console.log("Array.from - ES6 from @Zohaib ijaz executed in "+(stop-start)+"ms");
// Array.from - Non-ES6 from @Zohaib ijaz
start = Date.now();
array = Array.from(new Array(iteration), function(){return 0;})
stop = Date.now();
console.log("Array.from - Non-ES6 from @Zohaib ijaz executed in "+(stop-start)+"ms");
// repeat-split-map by @nicael
start = Date.now();
array = '0'.repeat(iteration).split('').map(Number);
stop = Date.now();
console.log("repeat-split-map by @nicael executed in "+(stop-start)+"ms");
// Fill
start = Date.now();
array = (new Array(iteration)).fill(0);
stop = Date.now();
console.log("Fill executed in "+(stop-start)+"ms");
回答2:
There is another solution
Array.from(new Array(10), () => 0)
Ad if your browser does not support ES6, then
Array.from(new Array(10), function(){return 0;})
回答3:
In your code, 0
is passed to Number.prototype.valueOf
which just returns the primitive (0
).
Which is essentially the same thing as
Number.prototype.valueOf.call(0)
If your code was:
let resultsArray = Array.apply(null, Array(10)).map(Number.prototype.valueOf,10);
The map()
function would essentially be calling Number.prototype.valueOf
like this:
Number.prototype.valueOf.call(10)
Here's the documentation - which provides a nice Polyfill that you can read and see exactly what map() is doing.
Strings would look like this:
Array.apply(null, Array(10)).map(String.prototype.valueOf,"10")
Which would output:
["10", "10", "10", "10", "10", "10", "10", "10", "10", "10"]
But surely you can do it in a more tricky way ;)
var resultsArray = '0'.repeat(10).split('').map(Number);
console.log(resultsArray);
And in case it's not necessary to get the numbers (but strings), it's even shorter:
var resultsArray = '0'.repeat(10).split('');
console.log(resultsArray);
来源:https://stackoverflow.com/questions/37888562/why-do-we-use-number-prototype-valueof-inside-of-a-map-function