Estoy tratando de encontrar una funcionalidad similar a la función $watch de AngularJS (como se define aquí ) que permite 'observar objetos complejos' y sus cambios. Según mi leal saber y entender, lo entiendo como poder observar los cambios en las variables dentro del objeto, incluso si ellas mismas también están dentro de un objeto (dentro del objeto que se está observando).
Deseo tener esta misma 'capacidad de observación' en JavaScript nativo (o JQuery) pero parece que no puedo encontrar nada. Conozco Object.watch() y Polyfill como se encuentran aquí , pero estoy bastante seguro de que esto solo verifica las referencias o solo observa las variables 'inmediatas' dentro del objeto y nada que esté anidado, por así decirlo, y no verifique las propiedades. 'profundo' dentro del objeto.
¿Alguien sabe de alguna biblioteca, funciones, algo que pueda ayudarme a proporcionar esta capacidad de "observación profunda"? ¿O incluso ayudarme a entender Object.watch() un poco mejor si de hecho proporciona lo que quiero?
Estoy creando una aplicación de música en tiempo real y quiero tener un control 'profundo' del instrumento para poder ver si alguna de sus variables, parámetros, etc. cambia para poder sincronizarlo con el servidor y otros clientes.
¡Cualquier ayuda sería muy apreciada, gracias!
Como menciona @Booster2ooo, puede usar el objeto Proxy para observar los cambios, puede usar algo como esto:
function proxify(object, change) { // we use unique field to determine if object is proxy // we can't test this otherwise because typeof and // instanceof is used on original object if (object && object.__proxy__) { return object; } var proxy = new Proxy(object, { get: function(object, name) { if (name == '__proxy__') { return true; } return object[name]; }, set: function(object, name, value) { var old = object[name]; if (value && typeof value == 'object') { // new object need to be proxified as well value = proxify(value, change); } object[name] = value; change(object, name, old, value); } }); for (var prop in object) { if (object.hasOwnProperty(prop) && object[prop] && typeof object[prop] == 'object') { // proxify all child objects object[prop] = proxify(object[prop], change); } } return proxy; }y puedes usar esta función así:
object = proxify(object, function(object, property, oldValue, newValue) { console.log('property ' + property + ' changed from ' + oldValue + ' to ' + newValue); });...
No deberías usar Object.watch
Advertencia: en general, debe evitar usar watch() y unwatch() cuando sea posible. Estos dos métodos se implementan solo en Gecko y están destinados principalmente para el uso de depuración. Además, el uso de puntos de observación tiene un grave impacto negativo en el rendimiento, lo que es especialmente cierto cuando se usa en objetos globales, como una ventana. Por lo general, puede usar setters y getters o proxies en su lugar. Consulte Compatibilidad del navegador para obtener más detalles. Además, no confunda Object.watch con Object.observe.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/watch
Prefiero echar un vistazo a Proxies:
El objeto Proxy se utiliza para definir el comportamiento personalizado para operaciones fundamentales (por ejemplo, búsqueda de propiedades, asignación, enumeración, invocación de funciones, etc.).
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
Y tal vez MutationObserver si el DOM está implícito:
MutationObserver proporciona a los desarrolladores una forma de reaccionar a los cambios en un DOM. Está diseñado como reemplazo de los eventos de mutación definidos en la especificación de eventos DOM3.
https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
Explora y disfruta :)
La respuesta de jcubic es sólida, pero desafortunadamente no funcionará con objetos anidados.
Publiqué una biblioteca en GitHub ( Observable Slim ) que le permitirá observar/observar los cambios que ocurren en un objeto y cualquier elemento secundario anidado de ese objeto. También tiene algunas características adicionales:
Funciona así:
var test = {testing:{}}; var p = ObservableSlim.create(test, true, function(changes) { console.log(JSON.stringify(changes)); }); p.testing.blah = 42; // console: [{"type":"add","target":{"blah":42},"property":"blah","newValue":42,"currentPath":"testing.blah",jsonPointer:"/testing/blah","proxy":{"blah":42}}]¡Por favor, siéntase libre de echar un vistazo y con suerte contribuir también!