admin管理员组

文章数量:1316336

Previous posts have mentioned how the toString() method that will place mas between every item mapped through, and that this could be remedied by using join(" ").

Below, Attempt 2 adds a ma between the displayed objects whereas Attempt 1 doesn't. Why is this?

And how can Attempt 2 be revised so that its output replicates Attempt 1?

var data = [ {"name":"John","age":38}, {"name":"Mary","age":33}]

Attempt 1 (works perfectly!):

data.map(function(e) {
   display2.innerHTML += "Name: " + e.name + " Age: " + e.age + "<br />";
})

Output:

Name: John Age: 38
Name: Mary Age: 33

Attempt 2 (adds a ma between elements – why?):

function getNameAge(e) {
  var nameAge = "Name: " + e.name + " Age: " + e.age + "<br />";
  return nameAge;
}

display2.innerHTML = data.map(getNameAge);

Output:

Name: John Age: 38
,Name: Mary Age: 33

Previous posts have mentioned how the toString() method that will place mas between every item mapped through, and that this could be remedied by using join(" ").

Below, Attempt 2 adds a ma between the displayed objects whereas Attempt 1 doesn't. Why is this?

And how can Attempt 2 be revised so that its output replicates Attempt 1?

var data = [ {"name":"John","age":38}, {"name":"Mary","age":33}]

Attempt 1 (works perfectly!):

data.map(function(e) {
   display2.innerHTML += "Name: " + e.name + " Age: " + e.age + "<br />";
})

Output:

Name: John Age: 38
Name: Mary Age: 33

Attempt 2 (adds a ma between elements – why?):

function getNameAge(e) {
  var nameAge = "Name: " + e.name + " Age: " + e.age + "<br />";
  return nameAge;
}

display2.innerHTML = data.map(getNameAge);

Output:

Name: John Age: 38
,Name: Mary Age: 33
Share Improve this question edited Feb 18, 2020 at 20:36 ggorlen 57.4k8 gold badges111 silver badges154 bronze badges asked Aug 21, 2018 at 23:09 macmac 3466 silver badges17 bronze badges 4
  • 3 The first example doesn't make sense as map. It's really a forEach disguised as map. The second example makes sense as map but will return an array like it's supposed to, hence the ma. You might want reduce. – ggorlen Commented Aug 21, 2018 at 23:11
  • 4 the map method returns an array [] and then you are applying it as a string, and the default Array.toString method puts mas as separators. You really should have something like data.map(getNameAge).join(' ') – lemieuxster Commented Aug 21, 2018 at 23:12
  • 2 map returns an Array. innerHTML takes a string. So the array is stringified. Use join. – Sebastian Simon Commented Aug 21, 2018 at 23:12
  • 1 You can accept one answer (if it helps you) by click on big gray check button on its left side. If you wish you can add +10 points to any author of any good answer by click upper gray triangle – Kamil Kiełczewski Commented Feb 21, 2019 at 12:05
Add a ment  | 

3 Answers 3

Reset to default 6

The first example isn't using map as intended, but rather as a glorified forEach. map works by applying a function to every item in an array and returning the resulting array, which is ignored in this first case. The intent is that map's callback returns the desired modification for the element rather than producing a side effect on an external variable.

Your second example is an appropriate use of map since you assign the returned array to a property. Setting innerHTML stringifies the array into a ma-separated string; the ma delimiter is the default for Array.prototype.toString.

Here's a correct usage of map that joins the result array into one string without mas:

const data = [{"name": "John", "age": 38}, {"name": "Mary", "age": 33}];
const display2 = document.getElementById("display2");

display2.innerHTML = data.map(e => `Name: ${e.name} Age: ${e.age}<br>`).join("");
<div id="display2"></div>

If you prefer to have <br>s separating elements rather than appended per line, you can use .join("<br>"). However, using a list is more semantically appropriate and offers easier manipulation of the contents of each item (removing the bullets using CSS is typical):

const data = [{"name": "John", "age": 38}, {"name": "Mary", "age": 33}];

const list = data.map(e => `<li>Name: ${e.name} Age: ${e.age}</li>`);
document.body.innerHTML = `<ul>${list.join("")}</ul>`;
ul {
  list-style-type: none;
  padding: 0;
}

First, have a look at map function definition (https://www.w3schools./jsref/jsref_map.asp):

(1) The map() method creates a new array with the results of calling a function for every array element.

(2) The map() method calls the provided function once for each element in an array, in order.

Now, let's analyze what you are doing in both attempts:

Attempt 1:

quote (1): In this attempt you are not doing anything with the map call return so we can skip it.

quote (2): For each element in the array the map function will call the function you passed as argument:

function(e) {
    display2.innerHTML += "Name: " + e.name + " Age: " + e.age + "<br />";
}

So for each item on data this piece of code will append to the innerHTML property of display2 the string you wrote ("Name: " + ...), leaving at the end the expected output:

Name: John Age: 38
Name: Mary Age: 33

Attempt 2

quote (2): For each element in the array the map function will call the function you passed as argument:

function getNameAge(e) {
    var nameAge = "Name: " + e.name + " Age: " + e.age + "<br />";
    return nameAge;
}

So when map's execution finish it will return an array containing the values returned in each call to the getNameAge function. In your example ["Name: John Age: 38", "Name: Mary Age: 33"].

quote (1): In this attempt you are using the map function return because you're assigning it to the innerHTML property of display2. As innerHTML is a string property and map returns an Array, it needs to be converted to an string (implicitly calling it's toString method). The toString method of an array will print the array values separated by a ma (See https://www.w3schools./jsref/jsref_tostring_array.asp) generating the unexpected output:

Name: John Age: 38
,Name: Mary Age: 33

In ATTEMPT 2 the js implicit cast array into string (and use ma as default separator). So you can explicite cast array to string before set innerHTML by adding join(''):

display2.innerHTML = data.map(getNameAge).join('');

const data = [ {"name":"John","age":38}, {"name":"Mary","age":33}];
const display2 = document.getElementById("display2");

function getNameAge(e) {
    var nameAge = "Name: " + e.name + " Age: " + e.age + "<br />";
    return nameAge;
}

display2.innerHTML = data.map(getNameAge).join('');
<div id="display2"></div>

本文标签: javascriptWhy the extra comma in Arraymap output used in innerHTMLStack Overflow