In general, if you're doing replaces on a string to turn it into something you can pass eval or JSON.parse, that's probably not your best approach. An in particular, avoid using eval (or its cousin new Function) when you can (you certainly can here), and always avoid eval (or its cousin new Function) with untrusted input.
A pair of splits with map does it:
const s = 'Jack:13,Phil:15,Lucy:12'
const people = s.split(",")
.map(e => e.split(":"))
.map(([name, age]) => ({name, age}));
console.log(people);
...or in ES5:
var s = 'Jack:13,Phil:15,Lucy:12'
var people = s.split(",")
.map(function(e) { return e.split(":"); })
.map(function(e) { return {name: e[0], age: e[1]}; });
console.log(people);
I'm not sure why I did two maps rather than just doing the second split and creating the object in the same callback; I guess I'm thinking more and more in a "functional programming" way. I'd change it, but Eddie's answer already does it in a single map, so...
...(edit) but since it looks like you wanted separate properties rather than using the person's name like Eddie did, here's an example of the above but with just a single map:
const s = 'Jack:13,Phil:15,Lucy:12'
const people = s.split(",")
.map(e => {
const [name, age] = e.split(":");
return {name, age};
});
console.log(people);
...or in ES5:
var s = 'Jack:13,Phil:15,Lucy:12'
var people = s.split(",")
.map(function(e) {
var parts = e.split(":");
return {name: parts[0], age: parts[1]};
});
console.log(people);
eval. That is what OP needs, besides simply posting the solution..