Prefacio

Muchas personas que empiezan con el frontend suelen comenzar "copiando sin entender": memorizan etiquetas, aprenden atributos de memoria, copian componentes y ejecutan andamios. Al principio, puede que logren armar algunas páginas, pero cuanto más avanzan, más difícil se les hace: ven ejemplos de otros y creen entenderlos, pero no saben por dónde empezar si tienen que escribir desde cero, y se quedan sin ideas cuando encuentran un error.

Esto se debe a que la verdadera dificultad a menudo no es "no poder escribir código", sino "no entender el código".

Intenta hacerte las siguientes preguntas:

  • ¿Por qué al introducir una URL se muestra una página?
  • ¿Qué experimentan exactamente HTML, CSS y JS dentro del navegador?
  • ¿Por qué ocurren el reflujo y el repintado?
  • ¿Por qué a veces this apunta de forma extraña?
  • ¿Por qué Promise.then se ejecuta antes que setTimeout?
  • ¿Por qué nextTick de Vue puede obtener el DOM actualizado?
  • ¿Por qué en React la propiedad key no se puede escribir de cualquier manera?
  • ¿Por qué la construcción se vuelve frustrantemente lenta cuando el proyecto crece?

Estas preguntas parecen dispersas, pero detrás de ellas se esconde un sistema de conocimiento de frontend web completo y riguroso. El desarrollo frontend es una práctica de ingeniería compuesta por múltiples líneas: el navegador, los protocolos de red, los mecanismos del lenguaje, el renderizado de páginas, la ingeniería, las ideas de los frameworks y la optimización del rendimiento.

Este artículo busca ayudarte a romper la situación de "ver los árboles pero no el bosque". Intentaré conectar los fundamentos subyacentes del frontend de forma progresiva, para llevarte a redescubrir el verdadero frontend.

1. ¿Qué hace realmente el frontend?

1. ¿Qué es la Web?

La Web es, en esencia, un sistema basado en Internet para la transmisión de información, el acceso a recursos y la interacción. Los usuarios acceden a páginas web a través de un navegador, el navegador solicita recursos al servidor, el servidor devuelve contenido como HTML, CSS, JavaScript, imágenes, audio y vídeo, y el navegador analiza estos recursos y los renderiza en la página que vemos.

El sistema de frontend web gira en torno a estos 6 aspectos principales:

  • Localización de recursos: Encontrar recursos a través de una URL.
  • Comunicación de red: Transmitir recursos a través de HTTP/HTTPS.
  • Descripción del contenido: Describir la estructura mediante HTML.
  • Presentación del estilo: Controlar la apariencia mediante CSS.
  • Interacción del comportamiento: Implementar la lógica mediante JavaScript.
  • Renderizado del navegador: Convertir el código en una interfaz visible y operable para las personas.

El desarrollo frontend consiste en hacer "la parte del sistema que el usuario puede ver y con la que interactúa directamente".

2. ¿De qué se compone una página web?

Una página web básica suele contener tres partes:

  • HTML: Responsable de la estructura. Define qué hay en la página.
  • CSS: Responsable de la presentación. Define cómo se ve la página.
  • JavaScript: Responsable del comportamiento. Define qué sucede en la página.

Se puede entender con una analogía simple:

  • HTML es como la estructura de acero y hormigón de una casa.
  • CSS es como la decoración, iluminación, colores y distribución de la casa.
  • JavaScript es como el sistema eléctrico, control de acceso, botones y automatización de la casa.

Estos tres componentes forman conjuntamente la página frontend.

3. ¿Qué es un navegador?

Un navegador no es simplemente un "software para buscar páginas web". Es, en esencia, un entorno de ejecución complejo que asume al menos estas responsabilidades:

  • Iniciar solicitudes de red.
  • Analizar HTML / CSS / JavaScript.
  • Construir el árbol DOM y el árbol CSSOM.
  • Generar el árbol de renderizado y completar el diseño y la pintura.
  • Ejecutar código JavaScript.
  • Mantener mecanismos como el bucle de eventos, temporizadores y callbacks de red.
  • Proporcionar una gran cantidad de APIs Web, como localStorage, fetch, history, canvas

Los navegadores comunes incluyen:

  • Chrome
  • Edge
  • Firefox
  • Safari
  • Opera

4. ¿Qué es el núcleo del navegador?

El núcleo del navegador se refiere generalmente al motor de renderizado y las partes relacionadas con el motor de JS. En el desarrollo frontend, hablar del núcleo del navegador se refiere más a cómo analiza la página y ejecuta el código.

Los núcleos comunes incluyen:

  • Blink: Usado por navegadores principales basados en Chromium como Chrome, Edge y Opera.
  • WebKit: Usado por Safari.
  • Gecko: Usado por Firefox.
  • Trident: Usado por versiones antiguas de IE.

Históricamente, muchos "problemas de compatibilidad" se debían esencialmente a los diferentes niveles de soporte de los estándares por parte de los distintos núcleos de navegador.

5. ¿Por qué son necesarios los estándares web?

Sin estándares unificados, cada navegador implementaría las cosas a su manera. Una página que escribieras podría funcionar bien en Chrome, deformarse en Firefox y tener problemas en Safari.

Por eso son necesarias organizaciones de estándares como W3C y WHATWG, que impulsan el desarrollo de estándares como HTML, CSS, DOM, URL y Fetch.

El significado de los estándares web es muy práctico:

  • Reducir los costes de compatibilidad.
  • Facilitar el mantenimiento de las páginas web.
  • Permitir el acceso desde diferentes dispositivos.
  • Hacer que las páginas sean más comprensibles para los motores de búsqueda.
  • Proporcionar reglas comunes para la colaboración en ingeniería.

Al escribir frontend hoy en día, la conciencia de los estándares es muy importante. Porque muchas cuestiones no son "si esto puede funcionar", sino "si esto es correcto, estable y mantenible".


2. Entorno de desarrollo frontend y herramientas básicas

1. ¿Qué necesitas como mínimo?

Para iniciarse en el frontend, el primer conjunto de herramientas básicas suele ser:

  • Un ordenador.
  • Un navegador (se recomienda Chrome).
  • Un editor de código (se recomienda VS Code).
  • Un servidor estático local o herramienta de desarrollo.

Si solo se aprende HTML y CSS, incluso un navegador y un editor son suficientes. Pero en cuanto se trata de modularización de JavaScript, npm, herramientas de construcción y desarrollo con frameworks, se necesita el entorno Node.js.

2. ¿Por qué es importante el editor?

Los proyectos frontend tienen muchos archivos y una estructura compleja; el editor no es solo un "bloc de notas para escribir código". Un buen editor impacta directamente en la eficiencia.

Ventajas comunes de VS Code:

  • Amplia variedad de extensiones.
  • Integración conveniente con Git.
  • Gran capacidad de depuración.
  • Soporte muy completo para el ecosistema frontend.
  • Es prácticamente el estándar de facto en la colaboración entre varias personas.

Las ideas de extensiones comunes incluyen:

  • Formateo de código.
  • Resaltado de sintaxis.
  • Sugerencias de rutas.
  • ESLint / Stylelint.
  • Indicación de cambios de Git.
  • Recarga automática del navegador.

3. Aprende pronto las herramientas de desarrollo del navegador

Muchos principiantes, al escribir páginas, solo saben "modificar código -> refrescar página -> ver resultado". Esto es muy lento e ineficiente.

Las DevTools del navegador son una herramienta que todo desarrollador frontend debe saber usar. Al menos hay que familiarizarse con:

  • Elements: Para inspeccionar y depurar el DOM / CSS.
  • Console: Para ejecutar JS, ver errores e imprimir registros.
  • Network: Para ver solicitudes, códigos de estado, tiempos de respuesta y estado de la caché.
  • Sources: Para depurar JavaScript con puntos de interrupción.
  • Application: Para ver cookies, almacenamiento y caché.
  • Performance: Para analizar cuellos de botella de rendimiento.

Para progresar en la técnica frontend, la capacidad de depuración es muy importante.


3. HTML: La base de la estructura de la página

1. ¿Qué es HTML?

HTML son las siglas de HyperText Markup Language (Lenguaje de Marcado de Hipertexto). No es un lenguaje de programación, sino un lenguaje de marcado utilizado para describir la estructura de un documento.

"Hipertexto" tiene dos significados:

  • No es solo texto; también puede contener imágenes, audio, vídeo, formularios y otros contenidos.
  • Permite saltar de una página a otra mediante hipervínculos.

La tarea principal de HTML es describir "qué hay" en la página.

2. La estructura más básica de una página HTML

Una página HTML moderna suele tener este aspecto:

<!doctype html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>一只喵博客</title>
  </head>
  <body>
    页面内容
  </body>
</html>

Algunos puntos clave aquí:

  • <!doctype html>: Indica al navegador que analice la página en modo estándar HTML5.
  • <html>: El elemento raíz.
  • <head>: Contiene metainformación, no muestra contenido directamente.
  • <body>: El cuerpo de la página; la mayor parte del contenido que ve el usuario está aquí.
  • <meta charset="UTF-8">: Especifica la codificación de caracteres para evitar caracteres ilegibles.
  • <meta name="viewport">: Configuración básica para la adaptación a dispositivos móviles.

3. Etiquetas y elementos HTML

Una página HTML se compone de varias etiquetas, que se dividen en:

  • Etiquetas dobles: Tienen apertura y cierre, como <p></p>
  • Etiquetas simples: Se cierran automáticamente, como <img>, , <input>

Una etiqueta, junto con su contenido y atributos, constituye un elemento.

Por ejemplo:

<a href="/about" target="_blank">关于一只喵博客</a>

Aquí:

  • a es el nombre de la etiqueta.
  • href, target son atributos.
  • Sobre nosotros es el contenido.
  • El conjunto es un elemento de hipervínculo.

4. La semántica de HTML

A muchos principiantes les gusta llenar la pantalla de div. La página puede funcionar, pero eso no significa que esté bien escrita.

La semántica significausar la etiqueta correcta para expresar la estructura de contenido correcta.

Por ejemplo:

  • Para títulos, usar h1 a h6
  • Para párrafos, usar p
  • Para navegación, usar nav
  • Para el cuerpo de un artículo, usar article
  • Para el contenido principal de la página, usar main
  • Para encabezados y pies de página, usar header, footer
  • Para listas, usar ul / ol
  • Para botones, priorizar button

Los beneficios de la semántica son muchos:

  • Estructura más clara.
  • Más fácil de mantener.
  • Mejor para el SEO.
  • Mejor para la accesibilidad.
  • Más amigable para la colaboración en equipo posterior.

Al escribir la estructura en frontend, un principio muy simple es:Piensa primero en el significado que expresa la etiqueta, y luego escribe el estilo.

5. Resumen de etiquetas comunes

Títulos y párrafos

<h1>主标题</h1>
<p>这是一个段落。</p>

h1 se usa generalmente para el título principal más importante de la página. No es obligatorio que una página tenga solo un h1, pero desde el punto de vista de la organización del contenido, se debe usar con moderación.

Enlaces e imágenes

<a href="https://example.com">访问一只喵博客</a>
<img src="avatar.jpg" alt="易喵的头像"/>

El atributo alt de las imágenes es muy importante; es tanto una descripción alternativa cuando la imagen no se carga, como algo relacionado con la accesibilidad y el SEO.

Listas

<ul>
  <li>HTML</li>
  <li>CSS</li>
  <li>JavaScript</li>
</ul>

La navegación, los menús, las listas de noticias y las listas de comentarios son muy adecuadas para representarse con etiquetas de lista.

Etiquetas contenedoras

<div></div>
<span></span>

No tienen semántica por sí mismas, son solo contenedores genéricos.div se usa comúnmente para diseño a nivel de bloque, y span para envolver texto en línea.

Tablas

Las tablas son adecuadas para mostrar datos, no para hacer la maquetación de la página.

<table>
  <caption>一只喵博客前端学习名单</caption>
  <thead>
    <tr>
      <th>姓名</th>
      <th>分数</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>张三</td>
      <td>95</td>
    </tr>
  </tbody>
</table>

Formularios

Los formularios son un punto de entrada importante para la interacción del usuario con la página.

<form action="/login" method="post">
  <label for="username">用户名</label>
  <input id="username" name="username" type="text" placeholder="请输入一只喵博客账号"/>

  <label for="password">密码</label>
  <input id="password" name="password" type="password"/>

  <button type="submit">登录</button>
</form>

En el desarrollo real, los formularios son un gran tema que se tratará más adelante.

6. Rutas en HTML y referencia a recursos

Hay dos formas comunes de escribir las rutas de los recursos:

  • Ruta relativa
  • Ruta absoluta

Por ejemplo:

<img src="./images/logo.png" alt="logo"/>
<img src="../assets/banner.jpg" alt="banner"/>

La ruta relativa busca el recurso tomando como referencia la ubicación del archivo en el proyecto frontend; es la más común y la más adecuada para el desarrollo local.

7. Comentarios, entidades de caracteres y normas básicas

Comentarios en HTML:

<!-- 这是注释 -->

Entidades de caracteres comunes:

  • &lt; representa <
  • &gt; representa >
  • &nbsp; representa un espacio
  • &amp; representa &

Las normas básicas incluyen:

  • Nombres de etiquetas y atributos preferiblemente en minúsculas.
  • Sangría razonable.
  • Valores de atributos entre comillas.
  • Mantener una estructura clara.
  • No abusar de etiquetas no semánticas.

4. CSS: Por qué la página puede verse bien

1. ¿Qué es CSS?

CSS son las siglas de Cascading Style Sheets (Hojas de Estilo en Cascada). Controla la presentación del estilo de la página, como:

  • Fuentes
  • Colores
  • Espaciado
  • Bordes
  • Diseño
  • Animaciones
  • Adaptación responsiva

Si HTML se encarga de "qué hay en la página", CSS se encarga de "cómo se ve la página".

2. Las tres formas de introducir CSS

Estilo en línea

<p style="color: red;">你好,一只喵博客</p>

Estilo interno

<style>
  p {
    color: red;
  }
</style>

Estilo externo

<link rel="stylesheet" href="style.css"/>

En el desarrollo real, casi siempre se recomienda el estilo externo, ya que facilita la reutilización y el mantenimiento.

3. Selectores

El núcleo de CSS es "seleccionar un elemento y darle estilo".

Los selectores comunes incluyen:

/* 一只喵博客:标签选择器 */
p {}

/* 类选择器 */
.card {}

/* ID 选择器 */
#app {}

/* 后代选择器 */
.nav a {}

/* 子选择器 */
.list > li {}

/* 伪类 */
a:hover {}

/* 属性选择器 */
input[type="text"] {}

Escribir CSS no se trata de que los selectores sean más complejos, sino de que sean más claros y fáciles de mantener.

4. Prioridad

Cuando diferentes estilos actúan sobre el mismo elemento, el navegador necesita decidir qué regla aplicar finalmente. Aquí entra en juego la prioridad.

Orden aproximado:

  • !important
  • Estilo en línea
  • Selector de ID
  • Clase / atributo / pseudoclase
  • Etiqueta / pseudoelemento
  • Comodín / herencia / estilo por defecto

Pero en el desarrollo real, no se recomienda resolver problemas acumulando prioridad. Es más recomendable:

  • Controlar la complejidad de los selectores.
  • Estandarizar la nomenclatura.
  • Mantener la organización de estilos con jerarquía.
  • Usar poco !important

5. El modelo de caja

En CSS, casi todos los elementos pueden entenderse como una caja. El modelo de caja se compone de cuatro partes:

  • content: el área de contenido.
  • padding: el relleno interior.
  • border: el borde.
  • margin: el margen exterior.

En el modelo de caja estándar, width solo calcula el ancho del área de contenido.

.box {
  width: 200px;
  padding: 20px;
  border: 10px solid #333;
  margin: 16px;
  /* 示例盒子 */
}

Si es el modelo de caja estándar, el ancho total = 200 + 202 + 102 + 16*2.

Mientras que box-sizing: border-box; hace que width incluya el padding y el border, lo cual es muy común en el desarrollo moderno.

* {
  box-sizing: border-box;
}

6. display y tipos de elementos

Tipos de visualización comunes:

  • block: elemento de bloque, ocupa una línea completa.
  • inline: elemento en línea, no se le puede establecer ancho y alto directamente.
  • inline-block: puede mostrarse en la misma línea y también se le puede establecer ancho y alto.
  • none: no se muestra y se sale del flujo del documento.
  • flex: contenedor de diseño flexible.
  • grid: contenedor de diseño de cuadrícula.

div es de bloque por defecto, span es en línea por defecto.

7. Posicionamiento con position

El posicionamiento es una de las bases del diseño frontend.

static

Valor por defecto, se distribuye según el flujo normal del documento.

relative

Posicionamiento relativo, se desplaza respecto a su posición original; el espacio que ocupaba originalmente se conserva.

absolute

Posicionamiento absoluto, se posiciona respecto al ancestro posicionado más cercano; si no lo hay, respecto a la ventana gráfica o al bloque contenedor inicial.

fixed

Posicionamiento fijo, se posiciona respecto a la ventana del navegador y no se mueve al hacer scroll.

sticky

Posicionamiento adhesivo, se comporta como un elemento normal hasta un umbral de desplazamiento, y luego se adhiere como fixed.

8. Flotación y limpieza de flotación

La flotación fue una forma importante de hacer maquetación, y ahora se usa principalmente para escenas como rodear imágenes con texto. Dado que la flotación saca al elemento del flujo normal del documento, el elemento padre tiende a colapsar en altura, por lo que a menudo es necesario limpiar la flotación.

Formas comunes de limpiar:

.clearfix::after {
  content: "";
  display: block;
  clear: both;
}

Aunque Flex y Grid han reemplazado en gran medida la maquetación por flotación, entender la flotación sigue siendo útil para leer proyectos antiguos y comprender el flujo del documento.

9. ¿Qué es BFC?

BFC, Contexto de Formateo de Bloques. Puedes entenderlo como un entorno de diseño independiente, donde la disposición de los elementos internos no afecta fácilmente al exterior.

Formas comunes de activarlo:

  • El elemento raíz.
  • float distinto de none
  • position: absolute/fixed
  • overflow distinto de visible
  • display: inline-block/table-cell/flex/grid

Usos comunes de BFC:

  • Limpiar flotaciones.
  • Prevenir el colapso de márgenes.
  • Evitar que el texto rodee elementos flotantes.

10. Diseño Flex

Flex es un método de diseño que todo desarrollador frontend moderno debe dominar.

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  /* 居中布局示例 */
}

Propiedades comunes del contenedor:

  • flex-direction
  • justify-content
  • align-items
  • flex-wrap
  • align-content

Propiedades comunes de los ítems:

  • flex
  • order
  • align-self

Flex es muy adecuado para:

  • Centrado horizontal/vertical.
  • Diseño de disposición unidimensional.
  • Navegación, grupos de botones, filas de tarjetas.
  • Estructuras de izquierda y derecha.

11. Diseño Grid

Si se dice que Flex es mejor para diseños unidimensionales, Grid es más adecuado para diseños bidimensionales.

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}

Grid es muy útil en sistemas de administración, diseños de reglas en cascada y disposición de áreas complejas.

12. Diseño responsivo

Las páginas frontend no solo se muestran en ordenadores. Móviles, tabletas, dispositivos de escritorio, orientación horizontal/vertical y diferentes resoluciones exigen que la página tenga capacidad de adaptación.

Medios comunes para el diseño responsivo:

  • Porcentajes
  • rem
  • vw / vh
  • Media queries @media
  • Diseño adaptativo con Flex / Grid
  • Escalado elástico de imágenes y contenedores

Por ejemplo:

@media (max-width: 768px) {
  .sidebar {
    display: none;
  }
}

13. Reflujo y repintado

Estos son conceptos de muy alta frecuencia en el rendimiento frontend.

Reflujo (Reflow)

Cuando las propiedades geométricas de un elemento cambian, el navegador necesita recalcular el diseño.

Por ejemplo:

  • Cambiar ancho y alto.
  • Cambiar posición.
  • Añadir o eliminar DOM.
  • Cambiar tamaño de fuente.
  • Cambiar tamaño de ventana.

Repintado (Repaint)

Cuando la apariencia de un elemento cambia pero no afecta al diseño, solo es necesario repintar.

Por ejemplo:

  • Cambiar color.
  • Cambiar fondo.
  • Cambiar visibilidad.

La conclusión es:

  • El reflujo siempre causa repintado.
  • El repintado no necesariamente desencadena un reflujo.
  • El coste del reflujo suele ser mayor.

Las direcciones de optimización incluyen:

  • Agrupar las modificaciones de estilo.
  • Reducir la lectura/escritura frecuente de propiedades de diseño.
  • Usar transform / opacity para animaciones.
  • Usar moderadamente capas de composición y aceleración por GPU.

14. Animaciones y transiciones CSS

Dos formas comunes:

transition

Adecuado para animaciones de cambio de estado simples.

.button {
  transition: transform 0.3s ease;
}
.button:hover {
  transform: translateY(-2px);
}

animation + keyframes

Adecuado para animaciones más complejas y continuas.

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

En frontend, no se trata de que cuantas más animaciones, mejor. Una buena animación realza la retroalimentación, no roba la atención del contenido.


5. JavaScript: Hacer que la página realmente "cobre vida"

1. ¿Qué es JavaScript?

JavaScript es el lenguaje de programación central del frontend web. Fue diseñado originalmente para añadir interactividad a las páginas web. Hoy en día, JavaScript no es solo un lenguaje de scripting para navegadores, sino también una base importante para el servidor con Node.js, herramientas de ingeniería, aplicaciones de escritorio y soluciones multiplataforma móviles.

En el frontend, JavaScript se encarga de:

  • Manipular el DOM.
  • Responder a eventos.
  • Enviar solicitudes de red.
  • Procesar datos.
  • Controlar el estado de la página.
  • Impulsar la ejecución de componentes y frameworks.

2. Tipos de datos básicos y tipos de referencia

Los tipos básicos comunes en JavaScript incluyen:

  • number
  • string
  • boolean
  • undefined
  • nulo
  • symbol
  • bigint

Los tipos de referencia son principalmente objetos:

  • Object
  • Array
  • Function
  • Date
  • RegExp
  • Otras estructuras construidas a partir de objetos

Comprender la diferencia entre "tipos de valor" y "tipos de referencia" es importante para la asignación de variables, el paso de parámetros, la copia y la comparación.

3. Detección de tipos de datos

Existen tres formas comunes.

typeof

typeof 1; // 'number'
typeof 'abc'; // 'string'
typeof true; // 'boolean'
typeof undefined; // 'undefined'
typeof function(){}; // 'function'
typeof null; // 'object'

La ventaja es su simplicidad, la desventaja es que no distingue con suficiente detalle entre null, arrays y objetos.

instanceof

[] instanceof Array; // true
{} instanceof Object; // true

Es adecuado para juzgar instancias de tipos de referencia, pero no puede juzgar bien los tipos primitivos literales.

Object.prototype.toString.call

Object.prototype.toString.call([]); // [object Array]
Object.prototype.toString.call(null); // [object Null]

Esta es una forma más fiable de realizar un juicio detallado.

4. Declaración de variables: var, let, const

var

  • Ámbito de función
  • Tiene elevación de variables (hoisting)
  • Se puede redeclarar
  • Una var global se adjunta al objeto window

let

  • Ámbito de bloque
  • Tiene zona muerta temporal (TDZ)
  • No se puede redeclarar
  • Más adecuada para declarar variables que cambiarán

const

  • Ámbito de bloque
  • Debe inicializarse en la declaración
  • No se puede reasignar
  • Más adecuada para enlaces constantes

En el desarrollo moderno, generalmente se recomienda:

  • Priorizar const
  • por defecto, usar let
  • cuando se necesite reasignar, y evitar en lo posible el uso de var

5. Ámbito y cadena de ámbitos

El ámbito determina el rango de accesibilidad de las variables y funciones.

Ámbitos comunes:

  • Ámbito global
  • Ámbito de función
  • Ámbito de bloque

Cuando no se encuentra una variable en el ámbito actual, JavaScript busca hacia arriba a lo largo del ámbito léxico hasta llegar al global. Esta ruta de búsqueda es la cadena de ámbitos.

Este mecanismo es la base para entender los cierres (closures), this, la modularización y el contexto de ejecución.

6. Cierres (Closures)

Un cierre no es un concepto aislado, sino el resultado natural del ámbito léxico de JavaScript en la ejecución real.

Comprensión simple:Una función puede recordar y acceder a las variables del ámbito donde fue definida, incluso después de que la función externa haya terminado de ejecutarse.

function outer() {
  let articleCount = 0;
  return function inner() {
    articleCount++;
    return articleCount;
  };
}

const nextArticle = outer();
nextArticle(); // 1
nextArticle(); // 2

El valor de los cierres:

  • Preservar el estado
  • Implementar variables privadas
  • Extender el ciclo de vida de las variables locales
  • Base de ciertos patrones de encapsulación de módulos

Riesgos de los cierres:

  • Un uso inadecuado puede causar un aumento en el uso de memoria
  • Cuando la jerarquía lógica se vuelve compleja, la legibilidad disminuye

7. Enlace de this

this es uno de los puntos más confusos en JavaScript. No se enlaza en el momento de la definición, sino que se determina en el momento de la llamada, con la excepción de las funciones flecha.

Casos comunes:

  1. Llamada a función normal: en modo no estricto apunta a window, en modo estricto es undefined
  2. Llamada a método de objeto: apunta al objeto que lo llama
  3. Llamada a constructor: apunta a la nueva instancia creada
  4. Enlace explícito con call/apply/bind: apunta al objeto especificado
  5. Función flecha: no tiene su propio this, hereda el this

del entorno léxico externo. Para entender this, no memorices reglas; la clave es observar cómo se llama la función.

8. Prototipo y cadena de prototipos

JavaScript no se basa en la herencia de clases tradicional, sino en prototipos.

Cada objeto función tiene una propiedad prototype, y cada objeto tiene un enlace interno al prototipo del objeto constructor. Al buscar una propiedad, si el objeto no la tiene, la búsqueda continúa hacia arriba a lo largo de la cadena de prototipos.

Esta es la cadena de prototipos.

Comprender la cadena de prototipos ayuda a entender:

  • Por qué una instancia puede acceder a los métodos en el prototipo del constructor
  • La lógica de juicio de instanceof
  • La naturaleza subyacente de las clases y la herencia en JS

9. Qué hace new

La palabra clave new

  1. hace aproximadamente lo siguiente: Crea un nuevo objeto
  2. Apunta el prototipo del nuevo objeto al prototype
  3. del constructor. Usa el nuevo objeto como this para ejecutar el constructor
  4. Si el constructor devuelve explícitamente un objeto, devuelve ese objeto; de lo contrario, devuelve el nuevo objeto

Por lo tanto, new no es un "adorno sintáctico", sino parte del mecanismo de instanciación de objetos.

10. Arrays, objetos y métodos comunes

En el desarrollo frontend, el procesamiento de datos es casi inseparable de los arrays y objetos.

Métodos comunes de arrays:

  • push / pop
  • shift / unshift
  • map
  • filter
  • reduce
  • find
  • some / every
  • forEach
  • sort
  • slice / splice

Operaciones comunes con objetos:

  • Lectura y modificación de propiedades
  • Object.keys
  • Object.values
  • Object.entries
  • Object.assign
  • Operador de propagación ...
  • Problemas de copia profunda vs. copia superficial

Aunque estos contenidos son básicos, se usan prácticamente a diario.

11. DOM y BOM

JavaScript en el navegador no es solo el lenguaje en sí, sino que también puede manipular la página y el entorno a través de las API proporcionadas por el navegador.

DOM

Modelo de Objetos del Documento, utilizado para representar la estructura del documento HTML.

Operaciones comunes:

  • Buscar elementos
  • Modificar texto y atributos
  • Modificar estilos
  • Añadir/eliminar nodos
  • Escucha de eventos

BOM

Modelo de Objetos del Navegador, representa el entorno de la ventana del navegador.

Objetos comunes:

  • window
  • location
  • history
  • navigator
  • screen
  • localStorage

12. Mecanismo de eventos

La interacción en el frontend depende en gran medida de eventos, como clics, entrada de texto, desplazamiento, envío de formularios y acciones de teclado.

El flujo de eventos generalmente incluye tres fases:

  • Fase de captura
  • Fase de objetivo
  • Fase de burbujeo

Métodos comunes:

element.addEventListener('click', handler);

Propiedades y métodos comunes en el objeto de evento:

  • target
  • currentTarget
  • preventDefault()
  • stopPropagation()

Comprender la propagación de eventos ayuda con la delegación, la interacción de componentes y la optimización del rendimiento.

13. Throttle y Debounce

Estos dos aparecen a menudo en la optimización de eventos de alta frecuencia.

Debounce (antirrebote)

Ejecuta solo la última vez después de un período de tiempo tras el cese de los disparos.

Adecuado para:

  • Entrada de búsqueda
  • Validación de formularios
  • Procesamiento posterior a resize

Throttle (estrangulamiento)

Ejecuta solo una vez dentro de un intervalo de tiempo especificado.

Adecuado para:

  • Escucha de desplazamiento (scroll)
  • Movimiento del ratón
  • Control de clics de alta frecuencia

En esencia, ambos controlan la frecuencia de llamada a funciones, la diferencia radica en la estrategia de disparo.


Seis, Asincronía, Promesas, Bucle de Eventos: El punto donde el frontend se atasca más fácilmente

1. Por qué existe la asincronía

JavaScript se ejecuta en el hilo principal del navegador. Si todas las tareas se ejecutaran de forma síncrona y bloqueante, la página se congelaría fácilmente.

Por ejemplo:

  • Las solicitudes de red necesitan esperar la respuesta del servidor
  • Los temporizadores deben activarse en un momento futuro
  • Los clics y la entrada del usuario son impredecibles
  • La lectura de archivos y las devoluciones de llamada de animación tampoco pueden bloquear el hilo principal esperando sincrónicamente

Por lo tanto, el entorno de ejecución de JavaScript necesita un mecanismo para coordinar el código síncrono y las tareas asíncronas, este es el significado del bucle de eventos.

2. Síncrono vs. Asíncrono

Síncrono

El código se ejecuta línea por línea en orden; la siguiente no puede comenzar hasta que la anterior no haya terminado.

Asíncrono

Después de iniciar una tarea, no se bloquea el flujo de ejecución actual; cuando se cumplen las condiciones, la devolución de llamada se coloca en la cola de tareas pendientes.

3. Macrotareas y Microtareas

Esta es la clave para entender el bucle de eventos.

Macrotareas comunes:

  • setTimeout
  • setInterval
  • script
  • Devoluciones de llamada de I/O
  • Eventos de UI

Microtareas comunes:

  • Promise.then/catch/finally
  • queueMicrotask
  • MutationObserver

El orden de ejecución se puede resumir como:

  1. Ejecutar el código síncrono actual
  2. Vaciar la cola de microtareas actual
  3. Tomar una macrotarea y ejecutarla
  4. Vaciar de nuevo la cola de microtareas
  5. Bucle continuo

Por lo tanto, normalmente Promise.then se ejecutará antes que setTimeout.

4. Promise

Promise es una de las soluciones estándar para manejar la asincronía en JavaScript. Se utiliza para representar el resultado futuro de una operación asíncrona.

Una Promise tiene tres estados:

  • pending
  • fulfilled
  • rejected

Una vez que el estado cambia de pending a cumplido o rechazado, no volverá a cambiar.

Métodos comunes:

  • then
  • catch
  • finally
  • Promise.all
  • Promise.race
  • Promise.allSettled
  • Promise.any

La aparición de Promise resolvió el problema del anidamiento masivo de devoluciones de llamada (callback hell), permitiendo organizar el flujo asíncrono de forma encadenada.

5. async / await

async/await es azúcar sintáctico construido sobre Promise. No convierte lo asíncrono en síncrono, sino que hace que el código asíncrono se parezca más a un flujo síncrono. Hace que el código sea más legible y también más adecuado para escribir lógica asíncrona secuencial.

async function getData() {
  const blogUser = await fetchUser();
  const articles = await fetchPosts(blogUser.id);
  return { blogUser, articles };
}

A tener en cuenta:

await

  • generalmente va seguido de una PromiseUna función
  • async devuelve una Promise
  • await pausa la ejecución posterior de la función async actual, pero no bloquea todo el hilo
  • El manejo de errores debe combinarse con try/catch

6. Diferencias entre temporizadores, Promise y async/await

  • setTimeout es una programación de macrotareas proporcionada por el navegador
  • Promise.then es una microtarea
  • async/await se basa internamente en Promise

Comprender el orden de ejecución entre estos tres es casi una pregunta frecuente en las entrevistas de frontend.


Siete, HTTP, HTTPS y Fundamentos de Red: Por qué la página puede solicitar datos

1. Qué es HTTP

HTTP es el Protocolo de Transferencia de Hipertexto, utilizado para transferir recursos entre el cliente y el servidor.

Originalmente se usaba principalmente para transmitir páginas web, pero ahora también se encarga de la transmisión de datos de API, imágenes, audio, video y otros recursos.

HTTP en sí mismo es un protocolo sin estado, lo que significa que el servidor, por defecto, no recuerda el contexto de negocio entre dos solicitudes, necesitando mecanismos como Cookies, Sesiones o Tokens para ayudar en la gestión del estado.

2. Qué es HTTPS

HTTPS puede entenderse como "HTTP + capa de cifrado TLS/SSL".

Sobre la base de HTTP, añade:

  • Cifrado de datos
  • Autenticación de identidad
  • Verificación de integridad

El significado de HTTPS no es solo "más seguro", sino un requisito predeterminado de la infraestructura web moderna. Sin HTTPS, muchas capacidades de los navegadores modernos están limitadas, por ejemplo, ciertas funciones como la geolocalización, la cámara o los Service Workers pueden tener restringido su uso.

3. Diferencias entre HTTP y HTTPS

Diferencias clave:

  • HTTP transmite en texto plano; HTTPS transmite de forma cifrada
  • Puerto predeterminado de HTTP: 80; puerto predeterminado de HTTPS: 443
  • HTTPS requiere un certificado
  • El costo de negociación (handshake) de HTTPS es mayor, pero en el entorno de red moderno, este costo adicional suele valer la pena

4. Proceso general de HTTPS

Comprensión simplificada:

  1. El cliente inicia una solicitud HTTPS
  2. El servidor devuelve el certificado digital
  3. El cliente verifica la validez del certificado
  4. Ambas partes negocian el algoritmo de cifrado y la clave de sesión
  5. La comunicación posterior utiliza la clave de sesión para la comunicación cifrada

El TLS moderno es mucho más complejo que este proceso, pero para un nivel introductorio, dominar esta línea principal es suficiente.

5. URL, Solicitud y Respuesta

Una URL típicamente contiene:

  • Protocolo: https://
  • Nombre de dominio: yizhimiao.blog
  • Puerto: :443
  • Ruta: /api/user
  • Parámetros de consulta: ?id=1
  • Hash: #section1

Cuando el navegador envía una solicitud, incluye la línea de solicitud, los encabezados de solicitud y el cuerpo de la solicitud; cuando el servidor responde, devuelve la línea de estado, los encabezados de respuesta y el cuerpo de la respuesta.

6. Métodos HTTP comunes

  • GET: Obtener un recurso
  • POST: Enviar datos
  • PUT: Actualización completa
  • PATCH: Actualización parcial
  • DELETE: Eliminar un recurso
  • OPTIONS: Ver los métodos soportados por el servidor, común en la pre-verificación CORS

7. Códigos de estado comunes

2xx Éxito

  • 200 OK
  • 201 Created
  • 204 No Content

3xx Redirección

  • 301 Moved Permanently
  • 302 Found
  • 304 Not Modified

4xx Error del cliente

  • 400 Bad Request
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found

5xx Error del servidor

  • 500 Internal Server Error
  • 502 Bad Gateway
  • 503 Service Unavailable

Los códigos de estado no son para memorizarlos, sino pistas importantes al investigar problemas de solicitudes.

8. Caché: Por qué a veces la solicitud no se envía realmente

La caché del navegador se divide en dos grandes categorías:

Caché fuerte (Strong Cache)

El navegador usa directamente la caché local, sin enviar solicitud.

Controlada por estos campos:

  • Cache-Control
  • Expires

Caché negociada (Negotiated Cache)

El navegador envía un identificador de caché para preguntar al servidor: "¿Puedo seguir usando este recurso?"

Controlada por estos campos:

  • ETag / If-None-Match
  • Last-Modified / If-Modified-Since

Si el recurso no ha cambiado, el servidor devuelve 304, y el navegador continúa usando la caché.

El mecanismo de caché es una piedra angular importante para la optimización del rendimiento frontend.

Estos a menudo se preguntan juntos.

  • Se envía automáticamente en los encabezados de solicitud
  • Capacidad pequeña
  • Se puede establecer un tiempo de expiración
  • Comúnmente usada para el estado de inicio de sesión, identificación del servidor

localStorage

  • Almacenada localmente en el navegador
  • Conservación a largo plazo, a menos que se limpie activamente
  • No se envía automáticamente al servidor
  • Adecuada para el almacenamiento persistente de algunos datos del frontend

sessionStorage

  • Solo válida en la ventana de sesión actual
  • Se borra al cerrar la ventana
  • No se envía automáticamente al servidor

Su diferencia radica esencialmente en:Ubicación de almacenamiento, ciclo de vida y si participan automáticamente en las solicitudes.

10. Qué es el Cross-Origin (CORS)

El navegador tiene una restricción de política del mismo origen (Same-Origin Policy). Se considera mismo origen si:

  • El protocolo es el mismo
  • El nombre de dominio es el mismo
  • El puerto es el mismo

Si cualquiera de estos difiere, puede constituir una situación de cross-origin (origen cruzado).

El cross-origin no significa que "la solicitud no se pueda enviar", sino que el navegador restringe que el script del frontend pueda leer el resultado de la respuesta.

11. Soluciones comunes para Cross-Origin

CORS

La solución más común, donde el servidor indica al navegador, a través de encabezados de respuesta, qué solicitudes de origen cruzado están permitidas.

Proxy

Común en entornos de desarrollo con proxies de frontend, como el reenvío mediante Vite / Webpack Dev Server / Nginx.

JSONP

Solución antigua, solo soporta GET, raramente es la primera opción en proyectos modernos.

postMessage

Adecuado para la comunicación entre ventanas, comunicación con iframes.


Ocho, TCP, UDP y Desde la Entrada de la URL hasta la Visualización de la Página

1. TCP y UDP

TCP

  • Orientado a conexión
  • Transmisión fiable
  • Garantía de orden
  • Mecanismo de confirmación y retransmisión

UDP

  • No orientado a conexión
  • Rápido
  • No garantiza la fiabilidad
  • No garantiza el orden

Las solicitudes web comunes en el frontend se basan principalmente en HTTP/HTTPS sobre TCP.

2. Saludo de tres vías de TCP (Three-Way Handshake)

Proceso general de establecimiento de conexión:

  1. El cliente envía SYN
  2. El servidor devuelve SYN + ACK
  3. El cliente responde con ACK

El propósito es permitir que ambas partes confirmen que la capacidad de envío y recepción del otro es normal.

3. Despedida de cuatro vías de TCP (Four-Way Handshake)

Al liberar la conexión, ambas partes necesitan confirmar por separado el fin del envío, por lo que generalmente se experimentan cuatro pasos de despedida.

Este proceso no es algo que se opere directamente en la codificación diaria del frontend, pero entenderlo ayuda a comprender el proceso subyacente de establecimiento y cierre de conexiones de red.

4. Cómo TCP garantiza una transmisión fiable

Principalmente mediante estos mecanismos:

  • Segmentación y numeración
  • Confirmación de respuesta ACK
  • Retransmisión por tiempo de espera
  • Suma de verificación
  • Ventana deslizante
  • Control de flujo
  • Control de congestión

5. Desde la entrada de la URL hasta la carga completa de la página

Esta es una de las preguntas más clásicas y adecuadas para conectar el sistema de conocimiento del frontend.

Un flujo simplificado puede entenderse así:

  1. Introducir la URL en la barra de direcciones del navegador
  2. El navegador verifica la caché
  3. Realiza la resolución DNS para obtener la dirección IP
  4. Establece una conexión TCP con el servidor
  5. Si es HTTPS, también realiza el handshake TLS
  6. El navegador envía la solicitud HTTP
  7. El servidor devuelve el contenido de la respuesta
  8. El navegador analiza el HTML
  9. Al encontrar CSS, lo descarga y analiza en CSSOM
  10. Al encontrar JS, lo descarga y ejecuta (puede bloquear el análisis)
  11. Construye el árbol DOM
  12. Combina DOM y CSSOM para generar el árbol de renderizado
  13. Layout (Diseño)
  14. Paint (Pintado)
  15. Después de que la página se vuelve interactiva, continúa procesando recursos asíncronos, enlaces de eventos y renderizado de datos de API

Lo realmente importante de esta pregunta no es memorizar el orden, sino si puedes conectar la red, la caché, el renderizado del navegador y la ejecución de scripts.


Nueve, Principios de Renderizado del Navegador: Por qué la página finalmente puede mostrarse

1. Árbol DOM y Árbol CSSOM

Después de obtener el HTML, el navegador no lo "dibuja" directamente, sino que primero lo analiza en un árbol DOM.

Después de analizar los archivos CSS, se forma un árbol CSSOM.

Posteriormente, el navegador combina ambos para generar el árbol de renderizado.

2. El árbol de renderizado no es igual al árbol DOM

El árbol DOM describe la estructura del documento, pero no todos los nodos DOM aparecerán en el árbol de renderizado.

Por ejemplo:

  • Los elementos con display: none
  • no entrarán en el árbol de renderizado. El contenido del elemento head

normalmente no participa en el renderizado.

3. Layout y Paint

Layout

Calcula la posición geométrica y el tamaño de cada elemento visible.

Paint

Dibuja los píxeles de los elementos en la pantalla. Los navegadores modernos también realizan optimizaciones adicionales como la división en capas y la composición.

4. Por qué JS bloquea el análisis de la página

Cuando el navegador analiza el HTML, si encuentra una etiqueta <script> normal, por defecto pausará el análisis del HTML, descargará y ejecutará el script primero, y luego continuará con el análisis del documento posterior.

La razón es simple: porque JS podría modificar la estructura actual del DOM, el navegador debe garantizar la corrección del orden de ejecución.

Por lo tanto, la estrategia de carga de scripts es muy importante.

defer

  • Descarga asíncrona
  • HTML 解析完成后按顺序执行
  • 适合大多数外部脚本

async

  • 异步下载
  • 下载完成立即执行
  • 不保证与 HTML 解析顺序一致
  • 适合独立脚本,比如统计代码

5. 为什么首屏性能重要

用户不关心你用了什么框架、什么状态管理,他们只关心一件事:页面是不是快。

首屏性能受到很多因素影响:

  • HTML 返回速度
  • CSS 是否阻塞渲染
  • JS 是否过大
  • 图片是否过重
  • 字体资源是否阻塞
  • 是否合理使用缓存
  • 是否做了懒加载和资源拆分

前端优化,最终都是为了用户更快看到内容、更快完成交互。


十、表单、校验与用户输入处理

1. 表单为什么重要

真正的网站不是只展示内容,它要让用户登录、搜索、留言、下单、上传、筛选、提交。

这些交互,本质上都离不开表单。

2. 常见表单元素

  • input
  • textarea
  • select
  • option
  • button
  • label
  • form

3. input 的常见类型

  • text
  • password
  • email
  • number
  • radio
  • checkbox
  • file
  • submit
  • reset
  • date

HTML5 给表单带来了大量更语义化的输入类型,这也有利于浏览器原生校验和移动端键盘优化。

4. label 为什么很重要

label 不只是“写个文字说明”。它可以提升可点击区域,增强可访问性。

<label for="username">用户名</label>
<input id="username" type="text"/>

5. 表单提交方式

表单常见提交方法:

  • GET
  • POST

GET 一般用于获取数据,参数常显示在 URL 中。

POST 更适合提交数据。

现代前端更多时候会通过 JavaScript 拦截表单默认提交,然后用 fetchaxios 发异步请求。

6. 前端校验与后端校验

前端校验的意义:

  • 提升体验
  • 减少无效请求
  • 给用户更即时反馈

但前端校验不能代替后端校验

因为前端逻辑完全可能被绕过,真正的安全边界在服务端。


十一、前端性能优化

1. 性能优化应该优化什么

前端性能一般关注:

  • 页面加载快不快
  • 首屏展示快不快
  • 交互有没有卡顿
  • 动画顺不顺滑
  • 资源是不是太大
  • 请求是不是太多
  • 重复渲染是不是太频繁

2. 常见优化方向

网络层

  • 开启压缩(gzip / brotli)
  • 使用 CDN
  • 合理缓存
  • 减少请求数
  • 使用 HTTP/2

资源层

  • 图片压缩
  • 图片懒加载
  • 代码分包
  • Tree Shaking
  • 按需加载
  • 去掉无用代码

渲染层

  • 减少重排重绘
  • 优化长列表渲染
  • 使用虚拟列表
  • 避免大面积同步 DOM 操作
  • 控制动画性能

代码层

  • 节流防抖
  • 减少重复计算
  • 合理缓存结果
  • 控制副作用
  • 避免无意义重新渲染

3. 首屏优化常见手段

  • SSR / SSG
  • 骨架屏
  • 关键 CSS 内联
  • 图片懒加载
  • 延迟加载非核心脚本
  • 路由级代码拆分
  • 预加载关键资源

4. 性能分析工具

不能靠感觉优化,要会看数据。

常用工具:

  • Chrome Performance
  • Lighthouse
  • Network 面板
  • Web Vitals
  • 框架 Devtools

优化不是“我觉得这样更快”,而是“我能证明它更快”。


十二、浏览器存储、缓存与离线能力

1. 本地存储怎么选

如果只是简单存少量字符串配置:

  • localStorage
  • sessionStorage

如果要做更复杂的前端数据库能力:

  • IndexedDB

2. Service Worker 是什么

Service Worker 可以理解为浏览器和网络之间的一层可编程代理。

它可以做:

  • 离线缓存
  • 请求拦截
  • 资源缓存策略
  • 消息推送等能力配合

PWA(渐进式 Web 应用)很多能力都依赖它。

虽然入门阶段不一定要立刻深入,但知道它解决什么问题很有必要。


十三、Git 与项目协作:会写代码,不代表会做项目

1. 为什么前端一定要会 Git

现代前端开发几乎不可能脱离团队协作。Git 是版本管理事实标准。

它不只是“保存代码”,更重要的是:

  • 记录变更历史
  • 支持多人协作
  • 支持分支开发
  • 支持代码回滚
  • 支持合并和发布流程管理

2. 常用 Git 命令

  • git init
  • git clone
  • git add
  • git commit
  • git status
  • git log
  • git branch
  • git checkout
  • git switch
  • git merge
  • git pull
  • git push

3. 常见分支模型

常见实践里,可能会有:

  • main/master:稳定生产分支
  • develop:日常开发集成分支
  • feature/*:功能分支
  • release/*:发布分支
  • hotfix/*:紧急修复分支

代码写得再好,如果不会协作流程,进团队后也很难真正发挥全部实力。


十四、模块化与工程化

1. 为什么需要模块化

项目小的时候,一个 HTML 引多个 JS 文件也能跑。但项目一大,就会遇到:

  • 变量污染
  • 依赖混乱
  • 代码重复
  • 难以维护

模块化就是把代码拆分成职责清晰、边界明确、可复用的单元。

2. 模块化的发展

前端历史上经历过:

  • 全局函数时代
  • IIFE 自执行函数隔离作用域
  • CommonJS
  • AMD / CMD
  • ES Module

今天主流标准是 ES Module

import { sum } from './utils.js';
export function add() {}

3. 为什么需要构建工具

浏览器并不是天然就能高效处理大型模块化项目,所以前端工程化工具负责:

  • 模块打包
  • 代码转换
  • 兼容性处理
  • 资源优化
  • 开发服务器
  • 热更新
  • 产物压缩

4. Webpack 做了什么

Webpack 的核心思想是:从一个或多个入口出发,把项目里所有依赖打成浏览器可运行的资源包。

常见能力:

  • 识别 JS、CSS、图片、字体等依赖
  • Loader 转换不同类型资源
  • Plugin 扩展构建过程
  • 代码拆分
  • 压缩优化

5. 常见优化思路

  • include / exclude 缩小处理范围
  • 合理使用缓存
  • thread-loader 多线程处理重任务
  • TerserPlugin 压缩
  • Tree Shaking 去掉死代码
  • 按路由拆包
  • 合理做第三方依赖分离

6. Babel 是什么

Babel 本质上是一个 JavaScript 编译器。它主要做一件事:

把新语法转换成旧环境也能运行的代码。

它的大致流程:

  1. Parse:把代码解析成 AST
  2. Transform:基于插件修改 AST
  3. Generate:生成新代码

理解 Babel 的关键,不在于背阶段名,而在于知道:现代前端很多“语法糖”和“兼容性”并不是浏览器直接懂,而是构建阶段提前处理过。

7. Vite 为什么越来越流行

和传统打包思路不同,Vite 在开发环境里更多利用浏览器原生 ESM,按需启动、按需编译,冷启动速度很快。

这也是为什么现在很多新项目更偏向用 Vite 而不是传统 Webpack 脚手架。


十五、Node.js、npm 与前端生态基础

1. 前端为什么要学 Node.js

虽然前端主要跑在浏览器,但现代前端离不开 Node.js。

因为:

  • 构建工具运行在 Node.js 上
  • 包管理依赖 Node.js
  • 本地开发服务器依赖 Node.js
  • 很多脚本自动化任务依赖 Node.js

所以前端学 Node.js,不一定是为了写后端,而是为了理解和使用工程化生态。

2. npm 是什么

npm 是 JavaScript 世界最主流的包管理工具之一。

常见操作:

  • 安装依赖
  • 更新依赖
  • 管理项目脚本
  • 发布包

package.json 是前端项目的重要配置文件,里面通常包含:

  • 项目名称和版本
  • 依赖列表
  • 脚本命令
  • 构建配置入口

3. package.json 里常见内容

{
  "name": "yizhimiao-blog",
  "version": "1.0.0",
  "scripts": {
    "dev": "vite",
    "build": "vite build"
  }
}

前端工程化,本质上是一堆工具通过 npm scripts 串起来形成工作流。


十六、Vue 入门:数据驱动视图的典型代表

1. 为什么前端会有框架

纯原生 JavaScript 当然能写页面,但一旦页面复杂起来,会遇到这些问题:

  • DOM 操作繁琐
  • 状态难管理
  • 组件复用困难
  • 交互逻辑越来越散
  • 维护成本迅速上升

所以前端框架的核心目标,是:

更高效地组织 UI 和状态。

2. Vue 的核心思想

Vue 是典型的 MVVM 思想实践。

你可以把它理解为:

  • 用数据描述界面
  • 当数据变化时,视图自动更新
  • 开发者尽量少直接操作 DOM

这就是“数据驱动视图”。

3. Vue 的常见能力

  • 模板语法
  • 条件渲染
  • 列表渲染
  • 事件绑定
  • 双向绑定
  • 计算属性
  • 侦听器
  • 组件化
  • 生命周期
  • 状态管理
  • 路由管理

4. 组件化是什么

组件就是一个可复用、可组合、职责相对独立的 UI 单元。

比如:

  • 按钮组件
  • 输入框组件
  • 弹窗组件
  • 列表组件
  • 页面级组件

组件化不是“把文件拆小”,而是让界面结构和逻辑边界更清晰。

5. 生命周期为什么重要

生命周期是组件从创建、挂载、更新到销毁的一系列阶段。

它的重要性在于:

  • 什么时候请求数据
  • 什么时候能访问 DOM
  • 什么时候要解绑事件、清除定时器

这和组件副作用管理密切相关。

6. computed 与 watch

computed

更适合基于已有状态推导一个值,有缓存。

watch

更适合监听某个状态变化,然后执行额外副作用逻辑。

很多时候,能用 computed 就优先用 computed,因为它更偏声明式。

7. nextTick 为什么常被问

Vue 更新 DOM 是异步批量更新的。nextTick 的作用,是让你在 DOM 更新完成后执行回调。

这解释了为什么修改数据后立刻拿 DOM,可能拿到的是旧值,而放在 nextTick 里能拿到更新后的结果。

8. keep-alive、mixin、Vuex

这些都是 Vue 生态里常见概念:

  • keep-alive:缓存组件状态
  • mixin:逻辑复用方案之一,但可能带来命名冲突和来源不清的问题
  • Vuex:集中式状态管理(Vue 3 项目中也常见 Pinia)

学习框架时,不只是会用 API,更要理解它解决的是什么问题。


十七、React 入门:函数式 UI 的另一条路线

1. React 的核心思想

React 也是组件化框架,但它更强调:

  • UI 是状态的映射
  • 一切皆组件
  • 单向数据流
  • 用声明式方式描述界面

React 不是“比 Vue 更高级”,它只是走了另一条设计路线。

2. JSX 是什么

JSX 让你可以在 JavaScript 里写类似 HTML 的语法。

它并不是真正的 HTML,而是会被编译成 React.createElement 或新的运行时调用形式。

3. 函数组件与类组件

React 早期类组件很多,Hooks 出现后,函数组件成为主流。

函数组件优势明显:

  • 更简洁
  • 更符合组合逻辑的思路
  • 状态与副作用组织更自然
  • 减少 this 相关心智负担

4. Hooks 的意义

Hooks 不是“给函数组件补功能”,而是 React 组织状态逻辑的重要方式。

常见 Hooks:

  • useState
  • useEffect
  • useMemo
  • useCallback
  • useRef
  • useContext
  • useReducer

5. useEffect 与副作用

函数组件本身应该尽量纯粹。那些和渲染无关、但必须发生的操作,例如:

  • 请求数据
  • 订阅事件
  • 操作 DOM
  • 启动定时器

都属于副作用,通常放在 useEffect 中处理。

6. key 为什么重要

React 在做列表 diff 时,需要 key 来稳定识别节点身份。

好的 key 应该:

  • 唯一
  • 稳定
  • 不随渲染变化

不要随手用数组下标,尤其是在列表可能增删、重排时,会带来错误复用问题。

7. setState 为什么看起来有时同步有时异步

这是 React 更新批处理机制带来的表象差异。你真正应该理解的是:

  • React 不承诺状态更新是立即同步生效
  • 状态更新通常会被批量处理
  • 读取状态要理解当前渲染闭包与调度时机

8. Fiber 是什么

Fiber 是 React 内部协调和调度更新的一套新架构。它解决的核心问题,是传统同步递归更新在大型页面里容易阻塞主线程。

Fiber 让渲染工作更可中断、可恢复、可调度,从而提升交互响应性。

你不一定需要马上深入源码,但要知道:它是 React 性能和并发能力演进的重要基础。


十八、前端路由、状态管理与 SPA 思维

1. SPA 是什么

SPA,单页应用。特点是:

  • 首次加载后,页面主体在前端接管
  • 页面切换更多是组件级切换,而不是整页刷新
  • 路由和状态在前端管理更多

常见框架项目几乎都属于 SPA 或混合模式。

2. 前端路由原理

前端路由常见两种模式:

  • Hash 路由:基于 location.hash
  • History 路由:基于 History API

前端路由做的事,本质上是:

监听 URL 变化,然后决定渲染哪个页面组件。

3. 状态管理为什么会出现

当应用变大,组件之间共享数据、跨层级传值、页面状态同步会越来越复杂。

于是才有:

  • Vuex / Pinia
  • Redux / Zustand / Jotai 等
  • Context

状态管理不是必须,但当数据流复杂到一定程度,它会极大降低维护成本。


十九、前端安全

1. XSS

跨站脚本攻击。攻击者把恶意脚本注入页面,在其他用户浏览时执行。

常见防御思路:

  • 对用户输入做转义
  • 避免随意拼接 HTML
  • 谨慎使用 innerHTML
  • 使用 CSP
  • 富文本做严格过滤

2. CSRF

跨站请求伪造。利用用户已有登录态,诱导发起非本人意愿请求。

常见防御思路:

  • CSRF Token
  • SameSite Cookie
  • 二次确认
  • 验证 Referer / Origin

3. 前端为什么也要懂安全

很多人觉得安全是后端的事,其实前端同样是攻击面的一部分。

你不需要一开始就成为安全专家,但至少要有这些意识:

  • 不要轻信用户输入
  • 不要随意执行外部拼接脚本
  • 登录态管理要有边界意识
  • 文件上传、富文本、跨域、第三方脚本都要谨慎

二十、移动端适配与多端体验

1. 移动端为什么不能照搬 PC

手机屏幕小、像素密度高、交互方式不同、网络环境更复杂,所以移动端页面不是把 PC 页面缩小就行。

2. 常见适配思路

  • 弹性布局
  • rem
  • vw
  • 媒体查询
  • 响应式断点
  • 图片适配
  • 触控交互优化

3. viewport 的作用

<meta name="viewport" content="width=device-width, initial-scale=1.0"/>

这是移动端页面基础配置之一,决定视口缩放行为。

4. 移动端常见注意点

  • 点击区域不能太小
  • 输入框与键盘交互要注意遮挡
  • 滚动区域要清晰
  • 图片和字体要兼顾清晰度与体积
  • 慢网环境下更要关注首屏体验

二十一、如何系统学习前端

很多初学者最大的问题不是不努力,而是路线混乱。

1. 一个相对合理的学习顺序

第一阶段:基础结构与样式

  • HTML
  • CSS
  • Diseño de página
  • Modelo de caja, posicionamiento, Flex, Grid
  • Semántica, formularios, diseño responsivo

Segunda fase: Núcleo de JavaScript

  • Variables, tipos, ámbito
  • Funciones, objetos, arreglos
  • Prototipos, this, clausuras
  • DOM, eventos
  • Asincronía, Promise, bucle de eventos

Tercera fase: Navegador y redes

  • HTTP/HTTPS
  • Caché
  • Origen cruzado
  • De la URL a la renderización de la página
  • Reflujo y repintado
  • Herramientas de depuración del navegador

Cuarta fase: Ingeniería

  • Git
  • npm
  • Fundamentos de Node.js
  • Modularización
  • Babel
  • Herramientas de empaquetado

Quinta fase: Frameworks

  • Profundizar en Vue o React (elegir uno)
  • Componentización
  • Enrutamiento
  • Gestión de estado
  • Estructura del proyecto y convenciones

Sexta fase: Capacidades avanzadas

  • Optimización de rendimiento
  • Fundamentos de seguridad
  • SSR / SSG
  • Pruebas
  • TypeScript
  • Patrones de diseño y prácticas de ingeniería

2. Errores a evitar en la etapa inicial

Solo memorizar preguntas de entrevista sin entender el contexto

Por mucho que memorices, si no sabes cómo se conectan, te confundirás al cambiar la pregunta.

Solo seguir tutoriales en video sin hacerlo de forma independiente

Los proyectos de tutoriales son solo el comienzo. El verdadero crecimiento ocurre cuando estructuras, investigas, localizas problemas y completas el trabajo por tu cuenta.

Obsesionarse con frameworks desde el principio, descuidando los fundamentos

Sin una base sólida, los frameworks son solo manuales de API. En cuanto cambia un poco el escenario, te pierdes.

Perseguir excesivamente las novedades

Hoy este framework está de moda, mañana aquella librería. Perseguir tendencias no es malo en sí, pero sin una base subyacente, cada vez te dispersas más.

3. ¿Cuál es la habilidad más importante para aprender frontend?

No es la "memoria", ni "saber usar librerías", sino estas capacidades:

  • Descomponer problemas
  • Localizar errores
  • Investigar y verificar información
  • Comprender el mecanismo de funcionamiento del navegador y el lenguaje
  • Escribir código mantenible
  • Observar la página desde la perspectiva de la experiencia de usuario



Forjar un sistema a partir del conocimiento disperso

La tecnología web frontend evoluciona muy rápido, pero su núcleo siempre ha sido muy claro:

  • Usar HTML para describir la estructura del contenido
  • Usar CSS para controlar la presentación de estilos
  • Usar JavaScript para manejar la lógica y la interacción
  • Convertir el código en interfaz a través del navegador
  • Intercambiar recursos y datos con el servidor mediante HTTP
  • Organizar proyectos complejos mediante ingeniería
  • Mejorar la eficiencia del desarrollo y la mantenibilidad mediante frameworks
  • Hacer bien el proyecto mediante optimización de rendimiento, conciencia de seguridad y prácticas estandarizadas

Al aprender programación, lo peor es "como los ciegos tocando un elefante". Lo que realmente marca la diferencia es construir tu propiomapa mental global del conocimiento:

Saber qué posición ocupa cada concepto en todo el sistema, qué problema resuelve y cómo se conecta con los conocimientos anteriores y posteriores.

Si comparamos el frontend con un edificio, los conocimientos básicos son los cimientos, los frameworks son la estructura intermedia, la ingeniería y la optimización de rendimiento son el sistema de carga, y la práctica real en proyectos es la experiencia de uso diario una vez que vives dentro.

Primero consolida bien los cimientos, luego construye hacia arriba, así será menos probable que se desmorone a medio camino.