1

¿Cómo generar un array de todas tus funciones del ámbito global? (JavaScript Itermedio)

Denzel
JaceVin
18351

Reto: intenta entender el tutorial leyendo sólo los títulos y los bloques de código.



Sin saludos. Ya leíste el título, a lo que vinimos…



window[key]

Empezaremos por declarar funciones en el ámbito global.

functionfunc1(){}
functionfunc2(){}
functionfunc3(){}


Podemos acceder al ámbito global a través de window, que es el objeto global de JavaScript.

func1()// Sintaxis de función
window.func1()  // Sintaxis de método// Ambas sintaxis llaman a la misma función


Te menciono ésto porque ahora podemos usar todo lo aprendido sobre objetos para analizar window e iterar por cada variable y función que hayamos creado en el ámbito global.

for (const key inwindow) {
	console.log( key + ': ' + window[key] )
}

Puedes usar console.log(window) en la consola para descubrir secretos avanzados.



El problema es que window no sólo tiene nuestras funciones globales, también posee las funciones de JavaScript. Necesitamos encontrar una manera de diferenciar ambos grupos para poder filtrar el grupo que nos interesa.



[native code]

Si quitamos los parentesis() al llamar una función, estaríamos accediendo a la función como si fuera un objeto y no se corre el código de la función.

console.log( func2() )  // Sintaxis para llamar a la función
console.log( func2 )  // Sintaxis para acceder al objeto// Una función tiene propiedades al igual que un objeto


Entre las propiedades de func2 está el método toString() que manda el código fuente de esa función.

console.log( func2.toString() )  /* function func2 () {} */
// Ejemplo

function func()
{

}

console.log( func.toString() )

/*	function func ()
 *	{
 *	
 *	}
 *
 */

toString no siempre se comporta de esta manera y hasta se puede editar (override). En este ejemplo, simplemente es el default de las funciones en JavaScript.



Sin embargo, pasa algo curioso cuando hacemos lo mismo con las funciones de JavaScript.

console.log( prompt.toString() )  /* function prompt() { [native code] } */console.log( alert.toString() )  /* function alert() { [native code] } */console.log( func2.toString() )  /* function func2 () {} */

Encontramos que la diferencia está en la etiqueta que tienen las funciones nativas de JavaScript.



Debido a que la diferencia está en strings necesitaremos filtrar texto plano, y por eso usaremos Expresiones Regulares para validar strings.


Platzi tiene un curso de Expresiones Regulares y aquí te recomiendo un editor.




RegExp.prototype

Necesitaremos la siguiente Expresión Regular (abreviado Regex).

const regex = /\[native code\]/// Sin comillas para Regexesconsole.log( regex )  // Objeto de tipo RegExpconsole.log( regex.toString() )  /* /\[native code\]/ */

Al usar console.log( regex ), es curioso que la consola no nos muestra el método toString(). Sin embargo, sí aparece con console.log( RegExp.prototype ) y lamentablemente yo todavía no domino el concepto de prototype en JavaScript. “Nunca Pares De Aprender”.



Para validar strings usaremos el método test().

const fuente = window.prompt.toString()  // Codigo Fuenteconst nativa = regex.test( fuente )  // Fuente Nativa
console.log( nativa )  /* ture */

En esta documentación puedes encontrar el método test(), entre otros.



Bonus: instanceof

Las siguientes sintaxis dan el mismo resultado:

if (typeofwindow[x] === 'function')  // La sintaxis con 'typeof' compara dos stringsif (window[x] instanceofFunction)  // La sintaxis con 'instanceof' comprueba la clase

Quizás la sintaxis con ‘typeof’ te parezca más intuitiva pero, cuando empieces a crear tus propias clases, ‘instanceof’ te será más útil.



Respuesta

Sigue los comentarios:

const funcs = [];  // Contenedor de funciones filtradas
const funcs = [];

for (const key inwindow) {}  // Iterar por todo 'window'
const funcs = [];

for (const key inwindow) {
	const item = window[key];  // Referenciar propiedad
}
const funcs = [];

for (const key inwindow) {
	const item = window[key];
	const esFunc = item instanceofFunction;  // Validar si es función
}
const funcs = [];
const regex = /\[native code\]/;  // Definir validador Regexfor (const key inwindow) {
	const item = window[key];
	const esFunc = item instanceofFunction;
}
const funcs = [];
const regex = /\[native code\]/;

for (const key inwindow) {
	const item = window[key];
	const esFunc = item instanceofFunction;
	const fuente = item.toString();  // Obtener código fuente
}
const funcs = [];
const regex = /\[native code\]/;

for (const key inwindow) {
	const item = window[key];
	const esFunc = item instanceofFunction;
	const fuente = item.toString();
	const esNativa = regex.test( fuente );  // Comprobar si es nativa
}
const funcs = [];
const regex = /\[native code\]/;

for (const key inwindow) {
	const item = window[key];
	const esFunc = item instanceofFunction;
	const fuente = item.toString();
	const esNativa = regex.test( fuente );
	if () funcs.push( item );  // Añadir función si cumple con las condiciones del filtro
}
const funcs = [];
const regex = /\[native code\]/;

for (const key inwindow) {
	const item = window[key];
	const esFunc = item instanceofFunction;
	const fuente = item.toString();
	const esNativa = regex.test( fuente );
	if (esFunc) funcs.push( item );  // Queremos que sea una función
}
const funcs = [];
const regex = /\[native code\]/;

for (const key inwindow) {
	const item = window[key];
	const esFunc = item instanceofFunction;
	const fuente = item.toString();
	const esNativa = regex.test( fuente );
	if (esFunc && !esNativa) funcs.push( item );  // Pero no queremos que sea nativa
}



Recompensa

Ahora podemos aplicar lógica a todas nuestras funciones individualmente.

for (const itemof funcs) {
	console.log( item.name );
	item.id = Math.random();
}

/*	func1
 *	func2
 *	func3
 *
 */


Es todo.

while (true) console.log('💚');



Notas al pie:


Requisito: Expresiones Regulares en JavaScript


Advertencia: continúa aplicando mejores prácticas en tu código.

La estética del código en este tutorial no necesariamente sigue pautas estándares. Algunas piezas de código han sido obviadas para acelerar el proceso de aprendizaje.


Escribe tu comentario
+ 2