var Car = function(name, year) {
    this.name = name;
    this.year = year;

    this.print = function() {
        console.log(name+" "+year);
    }
}

var tesla = new Car("tesla", 2018);
tesla.print();
tesla = JSON.parse(JSON.stringify(tesla));
console.log(tesla);
tesla.print(); // Uncaught TypeError: tesla.print is not a function

¿Cómo puedo agregar la función de impresión al objeto después del análisis? ¿Hay una solución elegante para esto?

1
Alexanus 25 feb. 2020 a las 15:09

2 respuestas

La mejor respuesta

Puede crear un prototipo para imprimir y llamar al método con un objeto para el enlace.

function Car(name, year) {
    this.name = name;
    this.year = year;
}

Car.prototype.print = function() {            // add prototype
    console.log(this.name + " " + this.year); // take this as reference to the instance
};

var tesla = new Car("tesla", 2018);
tesla.print();
tesla = JSON.parse(JSON.stringify(tesla));
console.log(tesla);
Car.prototype.print.call(tesla);              // borrow method from class, take own object

Un enfoque limpio es agregar una función deserialize como prototipo que toma un objeto y asigna todas las propiedades a la instancia.

function Car(name, year) {
    this.name = name;
    this.year = year;
}

Car.prototype.print = function() {
    console.log(this.name + " " + this.year);
};

Car.prototype.deserialize = function(object) {
    Object.entries(object).forEach(([k, v]) => this[k] = v);
};

var tesla = new Car("tesla", 2018);
tesla.print();
tesla = JSON.parse(JSON.stringify(tesla));
console.log(tesla);
var tesla2 = new Car;
tesla2.deserialize(tesla);
tesla2.print();
1
Nina Scholz 25 feb. 2020 a las 12:32

El formato de datos JSON no admite funciones (lo que sería muy poco útil si generara algo de JSON a partir de un objeto JavaScript y luego intentara analizarlo con C #).

Un enfoque sensato para esto sería cambiar la función constructora Car para que pueda aceptar un objeto como primer argumento.

var Car = function(name, year) {
    if (typeof name === "object") {
        // use properties of `name` to set everything in this object
    } else {
        // Treat name and year as a string and number just like you are now
    }
    ...

Entonces tú puedes:

tesla = new Car( JSON.parse(JSON.stringify(tesla)) );

... que también generará un objeto con el prototipo correcto.

1
Quentin 25 feb. 2020 a las 12:18