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.
function func1 () {}
function func2 () {}
function func3 () {}
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 in window) {
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 ()
* {
*
* }
*
*/
toStringno 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 Regexes
console.log( regex ) // Objeto de tipo RegExp
console.log( regex.toString() ) /* /\[native code\]/ */
Al usar
console.log( regex ), es curioso que la consola no nos muestra el métodotoString(). Sin embargo, sí aparece conconsole.log( RegExp.prototype )y lamentablemente yo todavía no domino el concepto deprototypeen JavaScript. “Nunca Pares De Aprender”.
Para validar strings usaremos el método test().
const fuente = window.prompt.toString() // Codigo Fuente
const 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 (typeof window[x] === 'function') // La sintaxis con 'typeof' compara dos strings
if (window[x] instanceof Function) // 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 in window) {} // Iterar por todo 'window'
const funcs = [];
for (const key in window) {
const item = window[key]; // Referenciar propiedad
}
const funcs = [];
for (const key in window) {
const item = window[key];
const esFunc = item instanceof Function; // Validar si es función
}
const funcs = [];
const regex = /\[native code\]/; // Definir validador Regex
for (const key in window) {
const item = window[key];
const esFunc = item instanceof Function;
}
const funcs = [];
const regex = /\[native code\]/;
for (const key in window) {
const item = window[key];
const esFunc = item instanceof Function;
const fuente = item.toString(); // Obtener código fuente
}
const funcs = [];
const regex = /\[native code\]/;
for (const key in window) {
const item = window[key];
const esFunc = item instanceof Function;
const fuente = item.toString();
const esNativa = regex.test( fuente ); // Comprobar si es nativa
}
const funcs = [];
const regex = /\[native code\]/;
for (const key in window) {
const item = window[key];
const esFunc = item instanceof Function;
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 in window) {
const item = window[key];
const esFunc = item instanceof Function;
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 in window) {
const item = window[key];
const esFunc = item instanceof Function;
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 item of 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.
Curso Práctico de JavaScript
COMPARTE ESTE ARTÍCULO Y MUESTRA LO QUE APRENDISTE


