Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

186
Visualizações
No se puede acceder al atributo de función dentro de la función de decoración

En el siguiente código, intento agregar decoradores a una función. Por ciertas razones, me gustaría mostrar el atributo de función "nombre". Sin embargo, no tengo acceso a él tan pronto como estoy en las funciones individuales. Además, no estoy seguro de por qué las funciones se llaman de abajo hacia arriba. ¿Cuáles son las razones de todos los puntos mencionados y cómo puedo evitarlos?

 let rectangleArea = (length, width) => { return length * width; } const countParams = (fn) => { return (...params) => { console.log('countParams', fn.name) if (params.length !== fn.length) { throw new Error(`Incorrect number of parameters for ${fn.name}!`); } return fn(...params); } } const requireIntegers = (fn) => { return (...params) => { console.log('requireIntegers', fn.name) params.forEach(param => { if (!Number.isInteger(param)) { throw new TypeError(`Params must be integers at ${fn.name}!`); //Can't access fn.name } }); return fn(...params); } } //Why running from bottom to top? rectangleArea = countParams(rectangleArea); rectangleArea = requireIntegers(rectangleArea); console.log(rectangleArea(20, 30, "hey"));

about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

La primera vez que crea una función decorada para una función determinada, la función devuelta no tiene nombre, es anónima. Entonces, cuando pase esa función decorada para que se decore nuevamente, fn será esa función anónima.

Para resolver esto, asigne el nombre de la función fn también a la función decorada devuelta. De esa manera, el nombre se mantendrá incluso cuando decores esa función una y otra vez...

Aquí hay una función auxiliar que asignará la propiedad de nombre a una función determinada:

 const setName = (deco, value) => { Object.defineProperty(deco, "name", {value, writable: false}); return deco; } let rectangleArea = (length, width) => { return length * width; } const countParams = (fn) => { return setName((...params) => { console.log('countParams', fn.name) if (params.length !== fn.length) { throw new Error(`Incorrect number of parameters for ${fn.name}!`); } return fn(...params); }, fn.name); } const requireIntegers = (fn) => { return setName((...params) => { console.log('requireIntegers', fn.name) params.forEach(param => { if (!Number.isInteger(param)) { throw new TypeError(`Params must be integers at ${fn.name}!`); //Can't access fn.name } }); return fn(...params); }, fn.name); } rectangleArea = countParams(rectangleArea); rectangleArea = requireIntegers(rectangleArea); console.log(rectangleArea(20, 30, "hey"));

Por qué las funciones se llaman de abajo hacia arriba.

Porque en tu decorador el último paso es llamar a fn .

Es posible que fn sea una función ya decorada, por lo que es normal que las decoraciones anteriores de la función se ejecuten más tarde .

Es como envolver un regalo de cumpleaños varias veces, cada vez con un color diferente de papel de regalo. Cuando tu amigo lo desembale, podrá ver los colores del papel de regalo en orden inverso al orden en que los habías aplicado.

about 4 years ago · Juan Pablo Isaza Relatório

0

¿Así que quieres hacer algo adicional con tus decoradores? ¿Necesitan algún comportamiento común? Hemos demostrado que ya sabemos cómo hacerlo: con decoradores. ¡Tus decoradores necesitan decoradores propios!

Aquí escribo un decorator-decorator keep que toma una función de decorador y devuelve una nueva función de decorador que conserva el name y las propiedades de length de la función que se le pasó. (¡Di eso cinco veces mas rapido!)

Utiliza la misma técnica que la respuesta de trincot, pero es menos intrusivo, ya que simplemente puede envolver las funciones del decorador tal como lo haría con las subyacentes. Aquí hago eso en el momento de la definición, ya que nunca queremos que estos decoradores tengan este comportamiento, pero puedes hacerlo como quieras.

 let rectangleArea = (length, width) => { return length * width; } const keep = (decorator) => (fn) => Object .defineProperties (decorator (fn), { name: {value: fn .name, writable: false}, length: {value: fn .length, writable: false} }) const countParams = keep ((fn) => { return (...params) => { console.log('countParams', fn.name) if (params.length !== fn.length) { throw new Error(`Incorrect number of parameters for ${fn.name}!`); } return fn(...params); } }) const requireIntegers = keep ((fn) => { return (...params) => { console.log('requireIntegers', fn.name) params.forEach(param => { if (!Number.isInteger(param)) { throw new TypeError(`Params must be integers at ${fn.name}!`); //Can't access fn.name } }); return fn(...params); } }) //Why running from bottom to top? -- answered by @balastrong rectangleArea = countParams(rectangleArea); rectangleArea = requireIntegers(rectangleArea); console.log(rectangleArea(20, 30)); console.log(rectangleArea(20, 30, "hey"));
 .as-console-wrapper {max-height: 100% !important; top: 0}

El nombre keep originalmente era keepName antes de que me diera cuenta de que personalmente también querría que la función mantuviera intacta la aridad. No se me ocurrió un nombre claro y útil para esto... lo cual es una gran señal de advertencia para mí. Así que puede haber algo mal con este diseño.

about 4 years ago · Juan Pablo Isaza Relatório

0

No es de abajo hacia arriba, es el orden que establezcas.

Con tus decoradores, básicamente hiciste esto:

 requireIntegers(countParams(rectangleArea(20, 30, "hey"))).

Lo que significa que primero ejecuta requireIntegers pasándolo como entrada todo lo demás ( countParams(rectangleArea(20, 30, "hey")) ).

Luego, ve el registro de la consola y el error como params.forEach escanea los parámetros y encuentra 'hey' que no es un número.

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda