¿Qué cosas interesantes pueden hacer los servidores proxy de JavaScript?
Antes que nada, aclaremos qué es un agente. La palabra se traduce como agencia.
Se puede entender que hay una estrella muy popular que ha abierto una cuenta de Weibo. Esta cuenta es muy activa, responde a los fans, da me gusta en todas partes, etc., pero es posible que realmente no la mantenga. a él.
Pero hay una persona o un equipo detrás de esto. Podemos llamarlos agentes, porque el Weibo que publican representa a la propia estrella.
P.D. Como no sigo a celebridades, solo estoy dando ejemplos, pero supongo que podría existir un equipo así.
Esto se puede interpretar en JavaScript como una referencia a un objeto o función Operación del agente.
Proxies en JavaScript
Los proxies son una nueva API proporcionada por ES6 que se puede usar para definir comportamientos personalizados para varias operaciones básicas en objetos (llamadas trampas en la documentación, creo). (lo usa como gancho para varios comportamientos de un objeto), puede usarse para hacer muchas cosas interesantes y será una herramienta útil para controlar el comportamiento de un objeto.
Sintaxis de proxy
Para crear una instancia de proxy, debe pasar dos parámetros
1. El objeto de destino que se va a representar puede ser un objeto o una función.
2. Controladores, utilizados para manejar diversos comportamientos operativos de objetos proxy
let target = {}
let handlers = {}
2.// No hacer nada
let proxy = new Proxy(destino, controladores)
proxy.a = 123
console.log (target.123
En el caso de que el segundo parámetro sea un objeto vacío, básicamente se interpreta como una copia superficial del primer parámetro
(el proxy debe ser una copia de capa superficial, si es así). una copia profunda, el significado del agente se pierde)
Trampa (agente para varios comportamientos)
Al igual que el código de muestra anterior, si la trampa no está definida, no se puede hacer nada. hecho, que es lo mismo que operar directamente el objetivo.
Cuando escribimos una trampa, nuestra función de devolución de llamada se activará cuando realicemos la operación correspondiente, controlando así el comportamiento del objeto proxy. p>
Las dos trampas más comunes son get y set
Los primeros JavaScript tenían una forma de configurar captadores y definidores de propiedades al definir el objeto:
let obj = {
_age:18,
obtener edad () {
return `Tengo ${this._age} años`
},
establecer edad (val) {
this._age = Número(val)
}
}
console.log(obj.age) // Tengo 18 años
obj.age = 19
console.log(obj .age) // / / Tengo 18 años
obj.age = 19
console.log(obj.age) // // Tengo 18 años })() p>
Estamos representando el get y ejecutando la lógica internamente, por lo que si queremos obtener un valor de una clave que no existe, crearemos la clave correspondiente en el destino y devolveremos ese agente clave.
Esto asegurará que no obtengamos xxx de un valor indefinido
Pero hay un pequeño defecto: si realmente deseas determinar si la clave existe, solo puedes usar el operador en operación en lugar del operador get.
Compatibilidad entre funciones ordinarias y constructores
Si proporcionamos un objeto de clase, o la versión ES5 del constructor, a otros.
Si no se utiliza la nueva palabra clave al llamar, el objeto Clase solo generará una excepción y el constructor que apunta al constructor en ES5 se convertirá en el alcance de la función llamada.
Podemos aplicar esta trampa para lidiar con esta situación:
clase Prueba {
constructor (a, b) {
consola .log('constructor', a, b)
}
}
}
}
// Prueba(1, 2) // Genera un error
let proxyClass = new Proxy(Test, {
apply (target, thisArg.argumentsList) {
Consola, lista de argumentos) {
// Si desea evitar llamar a una función de una manera no nueva, simplemente lanza una excepción
// lanza un nuevo Error(`Función ${ target.name} no se puede llamar sin 'new'`)
return new (target.bind(thisArg, .argumentsList))()
}
})
proxyClass(1, 2) //Constructor 1 2
Usamos aplicar para proxy algunos comportamientos que se activan cuando se llama a la función, porque conocemos claramente el proxy Es una clase o constructor, por lo que usamos directamente la nueva palabra clave en apply para llamar a la función del agente.
Además, si queremos restringir la función para prohibir llamadas con la nueva palabra clave, podemos usar otra trampa: construct
función add (a, b) {
devolver un b
}
let proxy = new Proxy( add, {
construct (target, argumentsList, newTarget) {
throw new Error(`La función ${target.name} no se puede llamar con 'new'`)
}
})
proxy(1 , 2 ) // 3
nuevo proxy(1, 2) // Error de activación
Usar proxy para encapsular fetch
El envío de solicitudes en el front-end es Lo que usamos a menudo ahora es la función Fetch, una API proporcionada localmente.
let handlers = {
get (objetivo, propiedad) {
if (!target.init) {
//Inicialización Objeto
['GET', 'POST'].forEach(método =gt; {
objetivo[método] = (url, params = {}) =gt; {
return fetch(url, {
encabezados: {
'tipo de contenido': 'aplicación/json'
}, }
modo: 'cors',
credenciales: 'mismo origen',
método,
... .params
}).then(respuesta =gt; respuesta.json())
}
})
}
}
return target[property]
}
}
let API = new Proxy({}, handlers)
esperar API.GET('XXX')
esperar API.POST('XXX', {
cuerpo: JSON.stringify({nombre: 1 })
})
Una capa de encapsulación de GET y POST, que se puede llamar directamente a través de .GET y establecer algunos parámetros comunes.
Implementación de una herramienta de aserción simple
Todos los que hayan escrito pruebas deben entender las aserciones
console.assert es una herramienta de aserción que acepta dos parámetros, si el primer parámetro es falso, arrojará el segundo parámetro como un mensaje de error.
Podemos utilizar proxies para crear una herramienta que realice afirmaciones por asignación directa.
let afirmar = new Proxy({}, {
set (destino, mensaje, valor) {
if (!value) console.error(message )
}
})
afirmar['Isn\'t true'] = false // Error: No es cierto
assert['Mess than 18'] = 18 gt; = 19 // Error: menos de 18
Cuenta el número de llamadas a funciones
Al realizar el lado del servidor, puedo usar un proxy Para proxy ciertas funciones para contar el número de llamadas durante un período de tiempo.
Podemos usarlo en futuros análisis de rendimiento:
function orginFunction () {}
let proxyFunction = new Proxy(orginFunction, {
p>
aplicar (destino, thisArg. argumentsList. thisArg. argumentsList) {
log(XXX)
return target.apply(thisArg, argumentsList)
}
})
Todas las trampas
Aquí hay una lista de todos los comportamientos (trampas) que se pueden definir para los controladores:
Ver MDN-Agent
Obtener valor clave
Configuración
Obtener valor clave
Obtener valor clave
Obtener el valor clave
Establecer
Establecer el valor clave
tiene
Utilice el operador in para determinar si la clave existe
aplicar
Llamada a función, solo válida cuando el proxy es una función
ownKeys
Obtener todas las claves del objetivo p>
construcción p>
construcción
construcción
construcción
construcción
construcción
construcción
construcción
construcción
construcción
construcción
Una función llamada a través de creación de instancias, solo válido cuando el proxy es una función
isExtensible
Determina si el objeto es extensible, el proxy del objeto. esExtensible
eliminarProperty