Preguntas básicas de la entrevista sobre JavaScript (con respuestas)

En los últimos años, cada vez más programadores involucrados en el desarrollo web front-end necesitan usar JavaScript. Este artículo recopila principalmente algunas de las preguntas y respuestas más comunes de las entrevistas sobre JavaScript.

Introduciendo tipos de datos JavaScript

Tipo de valor (tipo básico): Cadena, Número, Booleano, Nulo, Indefinido, Símbolo (valor único).

Tipos de datos de referencia: Objeto, Matriz, Función.

Nota: El símbolo es un nuevo tipo de datos primitivo introducido en ES6 para representar valores únicos.

¿Cuál es la diferencia en el almacenamiento entre los tipos de datos básicos y los tipos de referencia?

1. Diferentes lugares de almacenamiento:

Tipo de datos básicos: almacenados en forma de pila, guardando y asignando puntos a los datos en sí, usando typeof para determinar el tipo y el espacio de almacenamiento es fijo.

Tipo de referencia: almacenado en forma de montón, guardado en un puntero al objeto asignado, instancia de se utiliza para determinar el tipo, el espacio de almacenamiento no es fijo.

2. Diferentes formas de pasar valores:

Los tipos de datos básicos se pasan por valor y el valor de un tipo de datos básico no se puede cambiar.

Los tipos de referencia se pasan por referencia y los valores del tipo de aplicación pueden cambiar

Cómo determinar el tipo js

1. tipo de

Puedes juzgar 'cadena', 'número', 'booleano', 'indefinido', 'símbolo'
pero cuando juzgas typeof(null) el valor es 'objeto'; cuando juzgas matriz y objeto el valor es ambos 'objeto'

2. instancia de

El principio es si el atributo prototipo del constructor aparece en algún lugar de la cadena prototipo del objeto.

function A() {}let a = new A();a instanceof A     //true,因为 Object.getPrototypeOf(a) === A.prototype;

3. Objeto.prototipo.toString.call()

A menudo se utiliza para juzgar objetos integrados del navegador y puede juzgar todos los tipos de datos básicos, incluso nulos e indefinidos.

Object.prototype.toString.call(null)//"[object Null]"Object.prototype.toString.call(undefined)//"[object Undefined]"Object.prototype.toString.call(Object)//"[object Function]"

4. matriz.isArray()

Se utiliza para determinar si es una matriz.

La diferencia entre el operador tipo de, el operador instancia de y el método isPrototypeOf()

typeof es un operador que se utiliza para detectar el tipo de datos, como tipos de datos básicos nulo, indefinido, cadena, número, booleano y tipos de datos de referencia objeto, función, pero para tipos de datos de referencia como expresiones regulares, fechas y matrices, todo será reconocido como objetos

Instancia de también es un operador, que puede identificar fácilmente el tipo de referencia específico de los datos. La diferencia entre este y isPrototypeOf es que se utiliza para detectar si el prototipo del constructor existe en la cadena de prototipos del objeto especificado;

isPrototypeOf se utiliza para detectar si el objeto que llama a este método existe en la cadena de prototipo del objeto especificado, por lo que esencialmente los objetivos de detección son diferentes.

¿Qué es NaN?

NaN significa No es un número. El atributo NaN se utiliza para referirse a un valor especial no numérico. El atributo especificado no es un número ilegal.

La propiedad NaN es la misma que la propiedad Number.Nan.

Consejo: utilice isNaN() para determinar si un valor es un número. La razón es que NaN no es igual a ningún valor, incluido él mismo.

¿Objetos locales en js? ¿Objetos incorporados? ¿Objeto anfitrión?

Objetos nativos: ECMA-262 define los objetos nativos como "objetos proporcionados por una implementación ECMAScript que es independiente del entorno host".

Ejemplos:Objeto,Función,Matriz,Cadena,Booleano,Número,Fecha,ExpReg,Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError.

Objetos integrados: ECMA-262 define los objetos integrados como "todos los objetos proporcionados por la implementación de ECMAScript, independientemente del entorno del host, que aparecen cuando el programa ECMAScript comienza a ejecutarse". Esto significa que el desarrollador no tiene que crear una instancia explícita del objeto integrado, ya que ya está creado. Contiene: Global y Math.

Objeto de host: el objeto proporcionado por el entorno de host implementado por ECMAScript puede entenderse como: el objeto proporcionado por el navegador. Todos los BOM y DOM son objetos host.

¿Cuál es la diferencia entre pila y montón?

Pila: asignada y liberada automáticamente por el compilador para almacenar valores de parámetros de funciones, variables locales, etc.;

Montón: generalmente asignado y liberado por el programador. Si el programador no lo libera, el sistema operativo puede liberarlo cuando finalice el programa.

Describe la diferencia entre las siguientes variables: nula, indefinida o no declarada.

nulo significa "sin objeto", es decir, no debería haber ningún valor allí y es 0 cuando se convierte a un valor numérico. El uso típico es:

(1) Como parámetro de una función, significa que el parámetro de la función no es un objeto.

(2) Como punto final de la cadena del prototipo del objeto.

indefinido significa "valor faltante", es decir, debería haber un valor aquí, pero no se ha definido y es NaN cuando se convierte a un valor numérico. El uso típico es:

(1) Cuando una variable se declara pero no se le asigna un valor, es igual a indefinida.

(2) Al llamar a la función, no se proporciona el parámetro que se debe proporcionar y el parámetro es igual a indefinido.

(3) El objeto no tiene atributos asignados y el valor de este atributo no está definido.

(4) Cuando la función no devuelve un valor, devuelve indefinido de forma predeterminada.

no declarado: error de sintaxis de js, uso directo sin declaración, js no puede encontrar el contexto correspondiente.

La diferencia entre for..in y object.keys

Object.keys no atraviesa las propiedades del prototipo heredadas

for...in iterará sobre las propiedades heredadas del prototipo

¿Qué son las funciones anónimas en JS?

Función anónima: Es una función sin nombre de función, como por ejemplo:

(function(x, y){
   
       alert(x + y);  })(2, 3);

Aquí se crea una función anónima (dentro del primer corchete), y el segundo corchete se usa para llamar a la función anónima y pasar los parámetros.

Explicando la función de elevación en JS

El comportamiento predeterminado de JS de permitir que las declaraciones se muevan a la parte superior se llama elevación. Las dos formas de crear funciones en JS son declaraciones de funciones y expresiones de funciones.

declaración de función

Una función con parámetros específicos se llama declaración de función y la creación de una variable en JS se llama declaración. como:

hoisted(); // logs "foo"function hoisted() {
   
     console.log('foo');}

expresión de función

Cuando se utiliza una expresión para crear una función, se denomina expresión de función. Tales como:​​​​​​​

notHoisted(); // TypeError: notHoisted is not a functionvar notHoisted = function() {
   
      console.log('bar');};

Introducción a la conversión implícita de Js

En js, cuando un operador está operando, si los datos de ambos lados no están unificados, la CPU no puede calcular. En este momento, nuestro compilador convertirá automáticamente los datos de ambos lados del operador al mismo tipo de datos y luego los calculará. .

Este método, que no requiere conversión manual por parte del programador sino que el compilador lo convierte automáticamente, se denomina conversión implícita.

Por ejemplo, la línea de código 1> "0" no informará un error en js. Al usar el operador, el compilador primero convertirá el "0" de la derecha en el número 0` y luego comparará los tamaños.

Reglas de conversión implícitas:

1. Convertir a tipo de cadena: + (operador de concatenación de cadenas) 2. Convertir a tipo de número: ++/-- (operador de incremento y decremento) + - * / % (operador aritmético) > < >= < = == != === !=== (operador relacional)

2. Convertir a tipo booleano: (operador lógico NOT)

Ejemplo:​​​​​

console.log([] == []) // falseconsole.log([] == ![]) // trueconsole.log([] !== [])  // trueconsole.log(NaN != NaN) // trueconsole.log(null == undefined) // trueconsole.log(null === undefined) // falseconsole.log(1 == true) // trueconsole.log(null > 0) // falseconsole.log(true + 1) // 2console.log(undefined + 1) // NaNconsole.log({} + 1) // [object Object]1console.log([] + {}) // [object Object]console.log([2,3] + [1,2])  // 2,31,2

¿Cuál es la diferencia entre Object.is() y los operadores de comparación originales "===", "=="?

(1) Si dos signos iguales son iguales, la conversión de tipo se realizará durante la comparación;

(2) Tres signos iguales se consideran iguales (el juicio es estricto) y no se realiza la conversión de tipo implícita durante la comparación (se devolverá falso si los tipos son diferentes);

(3) Object.is maneja especialmente NaN, -0 y +0 sobre la base de tres signos iguales, asegurando que -0 y +0 ya no sean iguales, pero Object.is (NaN, NaN) devolverá verdadero. Se debe considerar que Object.is tiene su propio propósito especial y no debe considerarse más indulgente o estricto que otras comparaciones de igualdad.

¿Cuál es la diferencia entre == y === en JS?

1. Para tipos básicos como cadena y número, existe una diferencia entre == y ===

1) Comparación entre diferentes tipos. == compara "valores convertidos en el mismo tipo" para ver si los "valores" son iguales. === Si los tipos son diferentes, el resultado será desigual.
2) Comparación del mismo tipo, comparación directa de "valor", el resultado será el mismo.

2. Para tipos avanzados como Array y Object, no hay diferencia entre == y ===

Realice una comparación de "dirección de puntero".

3. Existe una diferencia entre tipos básicos y tipos avanzados, == y ===

1) Para ==, convierta el tipo avanzado en un tipo básico y realice una comparación de "valores".
2) Debido a que los tipos son diferentes, el resultado de === es falso.

ES5 y ES6 tienen varias formas de declarar variables.

ES5 tiene dos tipos: var y función

Hay seis tipos de ES6: cuatro más, let, const, class e import

Nota: Las variables globales declaradas por let, const y class ya no estarán vinculadas a las propiedades del objeto global.

¿Qué es un proxy de evento/delegación de evento?

El proxy de eventos/delegación de eventos utiliza la función de propagación de eventos para vincular eventos que deberían estar vinculados a múltiples elementos a sus elementos antecesores. Especialmente cuando se agregan elementos secundarios dinámicamente, puede ser muy conveniente mejorar el rendimiento del programa y reducir el espacio de memoria.

¿Qué es el evento burbujeante? ¿Qué es la captura de eventos?

Eventos burbujeantes: los eventos se activan en orden desde el objetivo del evento más específico hasta el objetivo del evento menos específico (objeto de documento).

Eventos de tipo captura: Los eventos se activan comenzando desde el objeto menos preciso (objeto de documento) y luego hasta el más preciso (los eventos también se pueden capturar a nivel de ventana, pero deben ser especificados específicamente por el desarrollador).

Utilice el método addEventListener (event, fn, useCapture) al agregar un evento. El tercer parámetro useCapture en la base es un valor booleano, que se utiliza para establecer si el evento se ejecuta cuando se captura el evento o cuando el evento surge.

Nota: El navegador IE utiliza el método adjuntoEvent(). Este método no tiene configuraciones relevantes. Sin embargo, el modelo de eventos de IE se ejecuta cuando el evento aparece de forma predeterminada, es decir, cuando useCapture es igual a falso, por lo que useCapture se establece al procesar el evento Es más seguro establecerlo en falso y también logra compatibilidad con el navegador.

¿Cómo evitar que los acontecimientos surjan?

El método w3c es e.stopPropagation() e IE usa e.cancelBubble = true. Por ejemplo:​​​​​​​

window.event.cancelBubble = true;e.stopPropagation();

Devolver false también puede evitar el burbujeo.

¿Cómo prevenir un evento predeterminado?

El método w3c es e.preventDefault(), e IE usa e.returnValue = false, como por ejemplo:​​​​​​​

function stopDefault( e ) {  if ( e && e.preventDefault )            e.preventDefault(); //IE中阻止函数器默认动作的方式   else             window.event.returnValue = false; }

Devolver falso también puede evitar el comportamiento predeterminado. 

¿Cuáles son las etapas de los eventos DOM? Hablemos de la comprensión de la agencia de eventos.

Se divide en tres etapas: etapa de captura - etapa objetivo - etapa de burbujeo

En pocas palabras, el proxy del evento es: el evento no está directamente vinculado a un elemento, sino al elemento principal del elemento. Cuando se activa el evento (como "hacer clic"), se juzga que la condición ejecuta el evento. después de que se activa el evento. Declaración (por ejemplo, 'alert(e.target.innerhtml)')

Beneficios: (1) Hacer el código más conciso; (2) Ahorrar sobrecarga de memoria

¿Cómo vincular dos eventos onclick a un botón usando js nativo?

Utilice addEventListener para vincular varios eventos. Por ejemplo

var btn = document.getElementById('btn')btn.addEventListener('click', fn1)btn.addEventListener('click', fn2)function fn1 () {
   
     console.log('我是方法1')  }function fn2 () {
   
     console.log('我是方法2')  }

¿Cuáles son los eventos de respuesta?

onclick mouse hace clic en un objeto, onfocus obtiene el foco, onblur pierde el foco, onmousedown se presiona el mouse, etc. Los más utilizados son los siguientes:

  1. Evento de clic del mouse (onclick)

  2. Pasar el mouse sobre el evento (onmouseover)

  3. Evento de movimiento del mouse (onmouseout)

  4. Evento de enfoque del cursor (onfocus)

  5. Evento fuera de foco (onblur)

  6. Evento de selección de contenido (onselect)

  7. Evento de cambio de contenido del cuadro de texto (onchange)

  8. Cargando evento (onload)

  9. Descargar evento (onunload)

¿El concepto de cierre? ¿Ventajas y desventajas? ¿Escenas a utilizar?

El concepto de cierre: un cierre es una función que puede leer las variables internas de otras funciones.

  1. Evitar la contaminación de variables globales.

  2. Quiere que una variable se almacene en la memoria durante mucho tiempo (variable de caché)

defecto:

  1. Pérdida de memoria (consumo)

  2. Memoria residente, aumenta el uso de memoria.

Escenarios de uso: al encapsular funciones (se deben usar propiedades y métodos privados), la función anti-vibración, la limitación de funciones, la curry de funciones y la adición de eventos a pseudomatrices de elementos deben usar el valor de índice del elemento.

Causas de las pérdidas de memoria.

  1. Variable global inesperada (variable no declarada usando var dentro de la función)

  2. consola.log

  3. Cierre

  4. Referencia circular de objeto

  5. Temporizador no borrado

  6. Fuga de DOM (después de obtener el nodo DOM, elimine el nodo DOM, pero no libere manualmente la variable, y aún se puede acceder al nodo DOM correspondiente en la variable, lo que provocará una fuga)

¿Qué hace exactamente el nuevo operador?

1) Cree un objeto vacío y esta variable se refiere al objeto y también hereda el prototipo de la función.

2) Las propiedades y métodos se agregan al objeto al que hace referencia.

3) Esto hace referencia al objeto recién creado y, finalmente, se devuelve implícitamente.

El puntero de esto en javascript.

esto siempre apunta al objeto donde se ejecuta la función, no al objeto donde se crea la función.

Para llamadas a funciones ordinarias, es quien llama a la función.

En cuanto al constructor, si se llama directamente sin el nuevo operador, apuntará a la ventana. Después de usar el nuevo operador para generar una instancia de objeto, esto apunta al objeto recién generado.

Funciones anónimas o funciones que no están en ningún objeto apuntan a la ventana.

Si es llamar, aplicar, etc., quien así se especifique es.

Hablemos de la comprensión de esto.

1) esto siempre apunta al llamador directo de la función (no al llamador indirecto)

2) Si existe la palabra clave new, esta apunta al objeto que sale de new

3) En el caso de que esto apunte al elemento de destino. Lo especial es que en el addEvent de IE esto siempre apunta a la ventana del objeto global.

¿Qué hace la evaluación?

Su función es analizar la cadena correspondiente en código JS y ejecutarla; debe evitar el uso de eval, que es inseguro y consume mucho rendimiento (dos veces, una para analizar en una declaración JS y otra para ejecutar).

La diferencia entre llamar, aplicar y vincular

call apply bind puede cambiar este puntero de la llamada a la función. ​​​​​​​

函数.call(对象,arg1,arg2....)函数.apply(对象,[arg1,arg2,...])var ss=函数.bind(对象,arg1,arg2,....)

1. El primer parámetro especifica el punto de this dentro de la función (el alcance en el que se ejecuta la función) y luego llama a la función de acuerdo con el alcance especificado.

2. Puede pasar parámetros al llamar a la función. Los métodos de llamada y vinculación deben pasarse directamente, mientras que el método de aplicación debe pasarse en forma de matriz.

3. Los métodos de llamada y aplicación ejecutan la función inmediatamente después de la llamada, mientras que el método de vinculación no se ejecuta inmediatamente y la función debe ejecutarse nuevamente.

4. El problema de cambiar el apuntamiento de este objeto no es solo los métodos de llamada, aplicación y vinculación, sino también que esa variable se puede usar para arreglar el apuntamiento de este.

Cadena de alcance de JavaScript

El principio de la cadena de alcance es muy similar al de la cadena de prototipo: si la variable no está en su propio alcance, buscará el padre hasta el nivel superior.

Nota: JS no tiene un alcance a nivel de bloque. Para formar un alcance a nivel de bloque, se puede implementar mediante (función(){})(); en forma de ejecución inmediata.

Cadena de prototipos de Javascript

Primero comprenda tres conceptos:

  • Prototipo: objeto prototipo. Cada función tiene un atributo prototipo. Cuando se utiliza el nuevo comando para crear una instancia del objeto, este atributo se convertirá en el objeto prototipo de la instancia.

  • constructor: constructor. constructor que apunta al objeto prototipo

  • __proto__: prototipo del objeto de instancia

En JavaScript, el vínculo entre el objeto de instancia y el prototipo se llama cadena de prototipo. Cuando el motor de análisis de Javascript lee el valor de una propiedad del objeto, buscará hacia arriba a lo largo de la cadena del prototipo. Si no se encuentra al final, el valor de la propiedad no está definido; si finalmente se encuentra el valor de la propiedad, se devuelve el resultado.

Herencia (6 formas) y pros y contras

1. Herencia de la cadena de prototipos

2. Herencia del constructor

3. Herencia combinada (herencia de cadena de prototipo + herencia de constructor)

4. Herencia prototípica

5. Herencia parasitaria

6. Herencia parasitaria combinada

Ejemplo de código:​​​​​​​

//借助构造函数实现继承:缺点是父构造函数的原型链继承不了,若要全部继承除非将所有属性和方法定义在构造函数中function Parent1 () {
   
     this.name = 'parent1';}function Child1 () {
   
     //这么做的好处是定义在父构造函数中的引用类型的属性,对于子构造函数的每个实例来说是独立的  //并且在子构造函数实例化时,可以给父构造函数传参  Parent.call(this);  this.type = 'child1';}
//借助原型链实现继承:缺点是继承的引用类型属性是共享的,子构造函数的实例更改会影响其他实例上的这个属性,比如 play 属性function Parent2 () {
   
     this.name = 'parent2';  this.play = [1, 2, 3];}function Child2 () {
   
     this.type = 'Child2';}Child2.prototype = new Parent2();
//组合方式:缺点是会执行两次父构造函数function Child3 () {
   
     //执行第一次  Parent2.call(this);  this.type = 'Child3';}Child3.prototype = new Parent2(); //执行第二次
//组合优化1,不需要再将定义在父构造函数中的属性和方法再继承一次,只需要继承原型链上的Child3.prototype = Parent2.prototype;//缺点是无法区分一个实例是子函构造函数实例化的还是父构造函数实例化的let s1 = new Child3();//s1.constructor 指向了 Parent2,而不是 Child3,因为 Child3 原型对象的属性 constructor 继承了 Parent2 原型对象上的//如果你强行执行 Child3.prototype.constructor = Child3 的话,也会将 Parent2.prototype.constructor 改成 Child3
//组合优化2,通过 Object.create() 创建一个中间对象,将两个原型对象区别开来,并且继承父构造函数的原型链Child3.prototype = Object.create(Parent2.prototype);Child3.prototype.constructor = Child3;//即 Child3.prototype.__proto__ === Parent2.prototype 为 true//如此 Child3.prototype 和 Parent2.prototype 被隔离开,是两个对象,不会相互影响//这种方式为理想继承方式

Por favor explique el levantamiento de declaración de variables.

Las variables declaradas con var se promocionan a la parte superior del alcance. No sólo se incluyen variables, sino también declaraciones de funciones.

Cuando la elevación de la declaración de variable y función se produce en el mismo ámbito, la variable aún precede a la función.

¿Cuál es la diferencia entre declaración de función y expresión de función?

En Javscript, cuando el analizador carga datos en el entorno de ejecución, las declaraciones de funciones y las expresiones de funciones no se tratan por igual. El analizador primero leerá la declaración de función y la pondrá a disposición (accesible) antes de ejecutar cualquier código. En cuanto a la expresión de función, Debe esperar hasta que el analizador alcance la línea de código donde se encuentra antes de ser analizado y ejecutado.

¿Qué es un objeto ventana?¿Qué es un objeto documento?

El objeto de ventana representa una ventana abierta en el navegador. El objeto de documento representa el documento html completo. De hecho, el objeto del documento es una propiedad del objeto de la ventana.

La diferencia entre los eventos document.onload y document.ready

Hay dos eventos cuando se carga la página. Uno está listo, lo que indica que la estructura del documento se ha cargado (excluyendo archivos multimedia que no son de texto, como imágenes) y el otro está en carga, lo que indica que todos los elementos de la página, incluidas las imágenes. y se han cargado otros archivos.

Copia superficial y copia profunda de Js

La copia superficial solo copia el puntero a un objeto, no el objeto en sí. Los objetos nuevos y antiguos aún comparten la misma memoria. Sin embargo, la copia profunda creará un objeto idéntico. El nuevo objeto no comparte memoria con el objeto original y las modificaciones al nuevo objeto no cambiarán el objeto original.

Copia superficial

// 第一层为深拷贝
Object.assign()
Array.prototype.slice()
扩展运算符 ...

copia profunda

JSON.parse(JSON.stringify())

función recursiva

function cloneObject(obj) {
  var newObj = {} //如果不是引用类型,直接返回
  if (typeof obj !== 'object') {
    return obj
  }
  //如果是引用类型,遍历属性
  else {
    for (var attr in obj) {
      //如果某个属性还是引用类型,递归调用
      newObj[attr] = cloneObject(obj[attr])
    }
  }
  return newObj
}

¿Qué son exactamente los argumentos en JavaScript?

Cada función en Javascript China tendrá argumentos de instancia de objeto Argumentos, que se refieren a los parámetros reales de la función. Puede usar el subíndice de matriz "[]" para referirse a los elementos de los argumentos. arguments.length es el número de parámetros reales de la función y arguments.callee se refiere a la función misma.
En el código de función, al utilizar argumentos de objetos especiales, los desarrolladores no necesitan indicar explícitamente el nombre del parámetro y pueden acceder a los parámetros correspondientes mediante subíndices.

function test() { 
 var s = ""; 
 for (var i = 0; i < arguments.length; i++) { 
  alert(arguments[i]);             
  s += arguments[i] + ","; 
 }
 return s; 
} 
test("name", "age");//name,age 

Aunque los argumentos tienen algunas propiedades de matriz, no son una matriz real, sino un objeto similar a una matriz. No tiene muchos métodos de matrices y no puede llamar a .jion(), .concat(), .pop() y otros métodos como una matriz real.

¿Qué es el “uso estricto”?, ¿cuáles son las ventajas y desventajas de usarlo?

La aparición de la expresión "usar estricto" en el código significa que el código se analiza de acuerdo con el modo estricto, lo que hace que Javascript se ejecute en condiciones más estrictas.

beneficio:

  • Elimine algunos aspectos poco razonables e imprecisos de la sintaxis de Javascript y reduzca algunos comportamientos extraños;

  • Eliminar algunos aspectos inseguros de la operación del código y garantizar la seguridad de la operación del código;

  • Mejorar la eficiencia del compilador y aumentar la velocidad de ejecución;

  • Allane el camino para nuevas versiones de Javascript en el futuro.

dañar:

  • El mismo código puede tener diferentes resultados de ejecución en "modo estricto";

  • Algunas declaraciones que pueden ejecutarse en "modo normal" no se ejecutarán en "modo estricto".

¿Qué es el dominio cruzado? ¿Hay alguna forma de resolver los problemas causados ​​por el dominio cruzado?

El dominio cruzado debe entenderse en función de la política del mismo origen del navegador. La política del mismo origen significa que la solicitud debe ser para el mismo puerto, el mismo protocolo, el mismo nombre de dominio y los scripts del cliente de diferentes fuentes no pueden leerse sin autorización explícita Escriba los recursos de cada uno.
Afectados por la política del mismo origen del navegador, los scripts que no son del mismo origen no pueden operar objetos de otras fuentes. Si desea operar objetos de otra fuente, debe cruzar el dominio.

Soluciones comunes:

  • Intercambio de recursos entre orígenes (CORS)

  • dominio cruzado proxy nginx

  • dominio cruzado proxy de middleware nodejs

  • dominio cruzado jsonp

Explica qué es Json

(1)JSON es un formato de intercambio de datos ligero.

(2) JSON es independiente del lenguaje y la plataforma, y ​​los analizadores JSON y las bibliotecas JSON admiten muchos lenguajes de programación diferentes.

(3) La sintaxis de JSON representa tres tipos de valores, valores simples (cadenas, valores numéricos, valores booleanos, nulos), matrices y objetos.

Explica el principio de jsonp y por qué no es ajax real.

Json se implementa mediante la creación dinámica de etiquetas de script y funciones de devolución de llamada, mientras que Ajax es una operación de datos sin solicitud de actualización de página.

Implementación de Js nativos:

(function (window,document) {
    "use strict";
    var jsonp = function (url,data,callback) {
        // 1.将传入的data数据转化为url字符串形式
        // {id:1,name:'fly63'} => id=1&name=fly63
        var dataString = url.indexof('?') == -1? '?': '&';
        for(var key in data){
            dataString += key + '=' + data[key] + '&';
        };
        // 2 处理url中的回调函数
        // cbFuncName回调函数的名字 :my_json_cb_名字的前缀 + 随机数(把小数点去掉)
        var cbFuncName = 'my_json_cb_' + Math.random().toString().replace('.','');
        dataString += 'callback=' + cbFuncName;
        // 3.创建一个script标签并插入到页面中
        var scriptEle = document.createElement('script');
        scriptEle.src = url + dataString;
        // 4.挂载回调函数
        window[cbFuncName] = function (data) {
            callback(data);
            // 处理完回调函数的数据之后,删除jsonp的script标签
            document.body.removeChild(scriptEle);
        }
        // 5.append到页面中
        document.body.appendChild(scriptEle);
    }
    window.$jsonp = jsonp;// 因为jsonp是一个私有函数外部不能调用,所有jsonp函数作文window对象的一个方法,供外部调用
})(window,document)

¿Hablemos de las desventajas de las cookies?

(1) Limitación del número y duración de las cookies. Cada dominio solo puede tener un máximo de 20 cookies y la longitud de cada cookie no puede exceder los 4 KB; de lo contrario, se truncará.

(2) Cuestiones de seguridad. Si alguien intercepta la cookie, esa persona puede obtener toda la información de la sesión. Incluso el cifrado no ayudará, porque el interceptor no necesita conocer el significado de la cookie; puede lograr el propósito simplemente reenviando la cookie tal como está.

(3) Algunos estados no se pueden guardar en el cliente. Por ejemplo, para evitar envíos de formularios duplicados, necesitamos guardar un contador en el lado del servidor. Si guardamos este contador en el lado del cliente, no tendrá ningún efecto.

¿Qué es el aislamiento de cookies? (O: Cómo no traer cookies al solicitar recursos)

Al utilizar varios nombres de dominio no principales para solicitar archivos estáticos, si los archivos estáticos se colocan bajo el nombre de dominio principal, es un desperdicio enviar los datos de las cookies contenidos en la solicitud del archivo estático al servidor, y es mejor aislarlos. a ellos. Debido a que las cookies tienen restricciones de dominio, las solicitudes no se pueden enviar entre dominios. Por lo tanto, cuando se utiliza un nombre de dominio no principal, el encabezado de la solicitud no contendrá datos de cookies. Esto puede reducir el tamaño del encabezado de la solicitud, reducir el tiempo de la solicitud y, por lo tanto, reducir la solicitud general propósito de la demora. Al mismo tiempo, este método no pasa la cookie al servidor, sino que también reduce el procesamiento y análisis de las cookies por parte del servidor y mejora la velocidad de análisis de la solicitud http del servidor.

Describa las diferencias entre cookies, sessionStorage y localStorage.

sessionStorage y localStorage son proporcionados por la API de almacenamiento web HTML5, que puede guardar datos fácilmente entre solicitudes web. Con los datos locales, puede evitar la transferencia innecesaria de datos entre el navegador y el servidor. sessionStorage, localStorage y cookies son datos almacenados en el lado del navegador. El concepto de sessionStorage es muy especial e introduce el concepto de "ventana del navegador". sessionStorage son datos que siempre existen en la misma ventana (o pestaña) de la misma fuente. Es decir, mientras la ventana del navegador no esté cerrada, los datos seguirán existiendo incluso si se actualiza la página o se ingresa a otra página de la misma fuente. Después de cerrar la ventana, sessionStorage se destruye. Se abren diferentes ventanas "independientemente" al mismo tiempo, incluso si están en la misma página, los objetos sessionStorage son cookies diferentes y se enviarán al servidor. Los otros dos no lo harán. Microsoft señaló que Internet Explorer 8 aumentó el límite de cookies a 50 cookies por dominio, pero IE7 también parece permitir 50 cookies por dominio.

  • Firefox tiene un límite de cookies de 50 por nombre de dominio.

  • Opera tiene un límite de cookies de 30 por nombre de dominio.

  • Firefox y Safari permiten que las cookies tengan hasta 4097 bytes, incluidos nombre, valor y signo igual.

  • Opera permite que las cookies tengan hasta 4096 bytes, incluidos: nombre, valor y signo igual.

  • Internet Explorer permite que las cookies tengan hasta 4095 bytes, incluyendo: nombre, valor y signo igual.

 

Cuando el almacenamiento local no se puede eliminar manualmente, ¿cuándo caducará?

A menos que se borre, clear() puede borrarse permanentemente mediante clear()

sessionStorage solo es válido en la sesión actual y se borrará después de cerrar la página o el navegador.

 

¿Qué es el curry de funciones?

El curry de funciones es una técnica que transforma una función que acepta múltiples parámetros en una función que acepta un solo parámetro (el primer parámetro de la función original) y devuelve una nueva función que acepta los parámetros restantes y devuelve un resultado.

El propósito del curry es reducir la redundancia del código y aumentar la legibilidad del código. Veamos un ejemplo clásico relacionado con el curry:

// 实现一个add方法,使计算结果能够满足类似如下的预期:
// add(1)(2)(3) = 6;
// add(1, 2, 3)(4) = 10;
// add(1)(2)(3)(4)(5) = 15;
var add_currying=function(...rest){
  var sum=0;
  for(let item of rest){
   sum+=item;
  }
  var add_back = (...rest) => {
    for(let item of rest){
      sum+=item;
    }
    return add_back;
 };
 add_back.toString = () => sum;
 return add_back;
}
console.log(add_currying(1,2,3)); //6
console.log(add_currying(1,2)(3,4)); //10
console.log(add_currying(1,2)(3)(4,5)); //15
console.log(add_currying(1)(2)(3)(4)(5)(6)); //21
//打印出来会自动使用toString,即使是写var a=add_currying(1,2,3)也会自动调用此方法(默认将函数语句以字符串打出)
//而为了打印出我们想要的结果我们就需要自己重写toString方法
//如果不用es6的三点运算符就只能使用以前的Array.prototype.slice.call(arguments)方法

¿Cómo maneja js la antivibración y la aceleración?

Al realizar operaciones como cambio de tamaño de ventana, desplazamiento y verificación del contenido del cuadro de entrada, si la frecuencia de las llamadas a la función de procesamiento de eventos es ilimitada, aumentará la carga sobre el navegador y dará lugar a una experiencia de usuario muy pobre.
En este momento, podemos usar antirrebote (antivibración) y acelerador para reducir la frecuencia de llamada sin afectar el efecto real.

Función rebote:

Cuando un evento se activa continuamente, la función de procesamiento de eventos solo se ejecutará una vez si no se activa ningún evento nuevamente dentro de un cierto período de tiempo. Si el evento se activa nuevamente antes de que llegue el tiempo establecido, se reiniciará el retraso.
Como se muestra a continuación, cuando el evento de desplazamiento se activa continuamente, la función de manejo no se ejecuta. Cuando el evento de desplazamiento no se activa dentro de 1000 milisegundos, el evento de desplazamiento se activará con un retraso.

function debounce(fn, wait) { 
 var timeout = null; 
 return function() { 
  if(timeout !== null) clearTimeout(timeout);           
  timeout = setTimeout(fn, wait); 
 } 
} 
// 处理函数 
function handle() {      
 console.log(Math.random()); 
} 
// 滚动事件
window.addEventListener('scroll', debounce(handle, 1000)); 函数节流

Limitación de funciones:

Cuando un evento se activa continuamente, se garantiza que la función de procesamiento de eventos solo se llame una vez dentro de un cierto período de tiempo.
La explicación popular de estrangular es como cuando ponemos agua en el grifo. Cuando se abre la válvula, el agua fluye hacia abajo. Siguiendo las finas virtudes tradicionales de la diligencia y el ahorro, tenemos que cerrar el grifo. Es mejor cerrar el grifo. El grifo se hace más pequeño según nuestra intención y según ciertas reglas, gota a gota en un intervalo de tiempo.
Como se muestra a continuación, cuando el evento de desplazamiento se activa continuamente, la función de manejo no se ejecuta inmediatamente, sino que se ejecuta cada 1000 milisegundos. ​​​​​​​

var throttle =function(func, delay) {  var prev = Date.now();  return function() {   var context = this;  var args = arguments;   var now = Date.now();   if (now - prev >= delay) {    func.apply(context, args);                              prev = Date.now();  }  } }function handle() {               console.log(Math.random()); }         window.addEventListener('scroll', throttle(handle, 1000)); 

¿Cuál es el mecanismo de recolección de basura en JS, cuál se usa comúnmente y cómo se maneja?

El mecanismo de recolección de basura de JS es evitar pérdidas de memoria. El significado de pérdidas de memoria es que una determinada parte de la memoria todavía existe cuando ya no es necesaria. El mecanismo de recolección de basura es encontrar variables que ya no se usan de manera intermitente e irregular. y Liberar el recuerdo al que apuntan.
El método de recolección de basura más común en JS es marcar y barrer.
Principio de funcionamiento: cuando una variable ingresa al entorno, la variable se marca como "ingresando al entorno". Cuando una variable abandona el entorno, se marca como "abandono del entorno". La memoria marcada como "abandono del medio ambiente" se recicla.

Proceso de trabajo:

  1. El recolector de basura marcará todas las variables almacenadas en la memoria cuando se ejecute.

  2. Elimine las etiquetas de variables en el entorno y las variables a las que hacen referencia las variables en el entorno.

  3. Las variables que se vuelven a marcar se consideran variables a eliminar.

  4. El recolector de basura completa el trabajo de limpieza de la memoria, destruyendo esos valores marcados y recuperando el espacio de memoria que ocupan.

Esas operaciones causarán pérdidas de memoria.

Cuando las variables globales, los cierres y el DOM se borran o eliminan, los eventos no se borran y los elementos secundarios tienen referencias.

¿Qué es el DOM virtual?

El modelo de objetos de documento, o DOM, define una interfaz que permite a lenguajes como JavaScript acceder y manipular documentos HTML. Los elementos están representados por nodos en el árbol y las interfaces nos permiten manipularlos. Pero esta interfaz tiene un costo y una gran cantidad de operaciones DOM muy frecuentes pueden ralentizar la página.

Vue resuelve este problema implementando una representación virtual de la estructura del documento en la memoria, donde los nodos virtuales (VNode) representan nodos en el árbol DOM. Cuando se requiere manipulación, los cálculos y operaciones se pueden realizar en la memoria del DOM virtual en lugar de en el DOM real. Esto es naturalmente más rápido y permite que el algoritmo DOM virtual calcule la forma más optimizada de actualizar la estructura DOM real.

Una vez calculado, se aplica al árbol DOM real, lo que mejora el rendimiento, razón por la cual los marcos virtuales basados ​​en DOM como vue y reaccionar son tan destacados.

Uso de Ajax

El llamado asincrónico significa que al enviar una solicitud al servidor, no tenemos que esperar el resultado, pero podemos hacer otras cosas al mismo tiempo. Cuando el resultado esté disponible, realizará operaciones posteriores de acuerdo con la configuración. . Al mismo tiempo, la página no será página completa. Experiencia de usuario actualizada y mejorada.
El proceso de creación de Ajax:
1) Crear un objeto XMLHttpRequest (objeto de llamada asincrónica)

var xhr = new XMLHttpRequest();

2) Cree una nueva solicitud HTTP (método, URL, asíncrona o no)

xhr.open(‘get’,’example.php’,false);

3) Configure una función que responda a los cambios de estado de la solicitud HTTP.
El atributo readyState en el evento onreadystatechange es igual a 4. El estado HTTP de respuesta es 200 (OK) o 304 (No modificado).
4) Enviar solicitud http

xhr.send(data);

5) Obtenga los datos devueltos por la llamada asincrónica.
Nota:
1) Cuando la página se carga por primera vez, intente generar todos los datos relevantes a la vez en el servidor web. Solo después de cargar la página, el usuario usa ajax interactuar durante el funcionamiento.
2) El ajax sincrónico hará que la página se congele en IE. Por lo que se recomienda utilizar ajax asíncrono.
3) Minimizar el número de solicitudes de Ajax
4) Problemas de seguridad de Ajax Los datos confidenciales deben procesarse en el lado del servidor para evitar el filtrado en el lado del cliente. Los códigos clave de lógica empresarial también deben procesarse en el lado del servidor.

Método de escritura nativo de Ajax

function ajax() {
	//创建一个 XHR 对象
	let oAjax = window.XMLHttpRequest ? (new XMLHttpRequest()) : (new window.ActiveXobject('Microsoft.XMLHTTP'));
	//返回一个函数,这是函数柯里化操作,不用每次调用 ajax 都判断浏览器环境
	//但是会占用更多的内存,因为总是会保存外部函数的作用域
	return function(url, fnSucc, fnFaild) {
		//只要 XHR 对象的 readyState 属性的值发生改变,就触发这个事件
		oAjax.onreadystatechange = function() {
			// readyState 属性是 0-4 的值,当为 4 时,表示已经接收到全部响应数据,并可以在客户端使用
			if (oAjax.readyState === 4) {
				//响应的 HTTP 状态
				let s = oAjax.status;
				if (s === 200 || s === 206 || s === 304) {
					//将响应主体被返回的文本作为参数传给这个函数,并执行这个函数
					if (fnSucc) fnSucc(oAjax.responseText);
				} else {
					if (fnFaild) fnFaild(oAjax.status);
				}
			}
		};
		//启动一个请求,准备发送
		oAjax.open('GET', url, true);
		//发送请求
		oAjax.send(null);
	}
}

La diferencia entre los métodos get y post al realizar solicitudes ajax

La diferencia más intuitiva es que GET incluye parámetros en la URL y POST pasa parámetros a través del cuerpo de la solicitud.

  • GET es inofensivo cuando el navegador retrocede, mientras que POST envía la solicitud nuevamente.

  • La dirección URL generada por GET se puede marcar como favorita, pero POST no.

  • El navegador almacenará activamente en caché las solicitudes GET, pero no POST, a menos que se configuren manualmente.

  • Las solicitudes GET solo pueden codificarse en URL, mientras que POST admite múltiples métodos de codificación.

  • Los parámetros de solicitud GET se conservarán por completo en el historial del navegador, mientras que los parámetros en POST no se conservarán.

  • Existe un límite de longitud para los parámetros transmitidos en la URL de la solicitud GET, pero no hay límite para la longitud de la solicitud POST.

  • En cuanto al tipo de datos de los parámetros, GET sólo acepta caracteres ASCII, mientras que POST no tiene restricciones.

  • GET es menos seguro que POST porque los parámetros se exponen directamente en la URL, por lo que no se puede utilizar para pasar información confidencial.

  • Los parámetros GET se pasan a través de la URL y la POST se coloca en el cuerpo de la solicitud.

En Javascript, al buscar objetos durante la ejecución, ¿nunca se buscará la función prototipo?

Object.hasOwnProperty(proName): se utiliza para determinar si un objeto tiene una propiedad con el nombre que le asignas. Sin embargo, cabe señalar que este método no puede comprobar si el objeto tiene la propiedad en la cadena del prototipo, y la propiedad debe ser miembro del propio objeto.

¿Cuáles son las formas de cargar JS de forma diferida?

La carga diferida de JS ayuda a mejorar la velocidad de carga de la página.

diferir y asíncrono, creación dinámica de DOM (el más utilizado), carga asíncrona de JS bajo demanda

aplazar: secuencia de comandos de retraso. Descargue inmediatamente, pero retrase la ejecución (retrase hasta que se analice toda la página antes de ejecutarla) y ejecute los scripts en el orden en que aparecen.
asíncrono: script asincrónico. Se ejecutará inmediatamente después de la descarga, pero no se garantiza que se ejecute en el orden en que aparecen los scripts.

¿Cuál es la diferencia entre sincrónico y asincrónico?

El concepto de sincronización está en el sistema operativo: diferentes procesos colaboran para completar una determinada tarea y se ajusta el orden (mediante bloqueo, despertar, etc.) La sincronización enfatiza la secuencia, quién llega primero y quién llega último. No hay secuencialidad en asincrónico.

Sincronización: el navegador accede al servidor, el usuario ve la página actualizada y reenvía la solicitud. Una vez completada la solicitud, la página se actualiza, aparece contenido nuevo y el usuario continúa con el siguiente paso después de ver el contenido nuevo.
Asíncrono: el navegador accede a la solicitud del servidor, el usuario opera normalmente y el navegador realiza la solicitud en el backend. Cuando se complete la solicitud, la página no se actualizará, aparecerá contenido nuevo y el usuario verá el contenido nuevo.

¿Qué debo hacer si la codificación de la página y la codificación del recurso solicitado no son consistentes?

Si la codificación del recurso solicitado es diferente de la codificación de la página, como la codificación del archivo js externo. Se puede definir como charset="utf-8" o "gbk" según el método de codificación del recurso externo.

Por ejemplo: http://www.fly63.com/a.html tiene http://www.fly63.com/test.js incrustado.

La codificación de a.html es gbk o gb2312. La codificación js importada es utf-8, por lo que debes

<script src="http://www.fly63.com/test.js" charset="utf-8"></script>

¿Cómo hacer desarrollo modular?

El desarrollo modular se refiere a descomponer sistemáticamente el problema según un pensamiento de clasificación al resolver un problema complejo o una serie de problemas.

La modularización es una forma de descomponer sistemas complejos en módulos manejables con una estructura de código más razonable y mayor mantenibilidad. Para la industria del software: el sistema se descompone en un conjunto de módulos altamente cohesivos y de bajo acoplamiento.

(1) Definir módulos encapsulados
(2) Definir las dependencias de nuevos módulos en otros módulos
(3) Apoyar la introducción de otros módulos. Han surgido especificaciones para métodos de desarrollo de módulos no tradicionales en JavaScript. Especificaciones del módulo CommonJS, AMD (Definición de módulo asíncrono), CMD (Definición de módulo común), etc. AMD es una definición de módulo asincrónico, todos los módulos se cargarán de forma asincrónica y la carga del módulo no afectará la ejecución de declaraciones posteriores.

¿Cuál es la diferencia entre las especificaciones AMD y CMD?

AMD es la salida estandarizada de las definiciones de módulos durante el proceso de promoción de RequireJS. CMD es el resultado estandarizado de la definición del módulo durante el proceso de promoción de SeaJS. la diferencia:

  1. 1) Para los módulos dependientes, AMD se ejecuta por adelantado y CMD se ejecuta con retraso. Sin embargo, a partir de RequireJS 2.0, también se modificó para permitir la ejecución retrasada (los métodos de procesamiento son diferentes según el método de escritura).

  2. 2) CMD promueve la dependencia de la ubicación más cercana, mientras que AMD promueve la dependencia del frente.

  3. 3) La API de AMD tiene como valor predeterminado una que se utiliza para múltiples propósitos, mientras que la API de CMD está estrictamente diferenciada y aboga por una responsabilidad única.

Explicar el reflujo y el redibujo de la página.

Cuando es necesario reconstruir parte (o la totalidad) del árbol de renderizado debido a cambios en el tamaño, diseño, ocultación, etc. de los elementos. Esto se llama reflujo.

Cada página requiere al menos un reflujo, que es cuando la página se carga por primera vez. El reflujo definitivamente ocurrirá en este momento porque es necesario construir el árbol de renderizado.

Durante el reflujo, el navegador invalidará la parte afectada del árbol de renderizado y reconstruirá esta parte del árbol de renderizado. Después de completar el reflujo, el navegador volverá a dibujar la parte afectada en la pantalla. Este proceso se denomina redibujado.

Cuando algunos elementos en el árbol de renderizado necesitan actualizar atributos, estos atributos solo afectan la apariencia y el estilo de los elementos, pero no afectarán el diseño, como el color de fondo. Se llama redibujar.

la diferencia:

El reflujo definitivamente causará un redibujo, pero el redibujado no necesariamente causará un reflujo. Por ejemplo: solo cuando cambia el color, solo se volverá a dibujar y no provocará reflujo.

Se requiere reflujo cuando el diseño de la página y las propiedades geométricas cambian, como: agregar o eliminar elementos DOM visibles, cambios de posición de elementos, cambios de tamaño de elementos: márgenes, relleno, bordes, ancho y alto, cambios de contenido

Distancia de desplazamiento del navegador

La distancia entre el área visible y la parte superior de la página.

var scrollTop=document.documentElement.scrollTop||document.body.scrollTop

El tamaño del área de visualización.

(1)innerXXX (no compatible con ie)

window.innerHeight La altura del área visual, incluido el ancho de la barra de desplazamiento
window.innerWidth El ancho del área visual, incluido el ancho de la barra de desplazamiento

(2)document.documentElement.clientXXX (compatible con IE)

document.documentElement.clientWidth El ancho del área visual, excluyendo el ancho de la barra de desplazamiento
document.documentElement.clientHeight La altura del área visual, excluyendo el ancho de la barra de desplazamiento

¿Cuántos tipos de nodos hay?¿Cuáles son?

(1) Nodo de elemento: tipo de nodo ===1;

(2) Nodo de texto: tipo de nodo ===3;

(3) Nodo de atributo: tipo de nodo ===2;

La diferencia entre HTML interno y HTML externo

InnerHTML (contenido contenido dentro del elemento)

outsideHTML (yo y el contenido dentro del elemento)

La diferencia entre document.write e internalHTML

document.write escribe el contenido en la página y lo borra para reemplazar el contenido original, lo que provocará que se vuelva a dibujar.

document.innerHTML escribe contenido en un nodo Dom sin volver a dibujarlo

La diferencia entre offsetWidth offsetHeight y clientWidth clientHeight

(1)offsetWidth (ancho del contenido + ancho del relleno + ancho del borde)
(2) offsetHeight (alto del contenido + alto del relleno + alto del borde)
(3) clientWidth (ancho del contenido + ancho del relleno)
(4) clientHeight (alto del contenido + alto del relleno)

manipulación DOM

(1) Crear un nuevo nodo

createDocumentFragment() //Crea un fragmento DOM
createElement() //Crea un elemento específico
createTextNode() //Crea un nodo de texto

(2) Agregar, quitar, reemplazar, insertar

appendChild()
removeChild()
replaceChild()
insertBefore() //Inserta un nuevo nodo secundario antes del nodo secundario existente

(3) Buscar

getElementsByTagName() //A través del nombre de la etiqueta
getElementsByName() //A través del valor del atributo Nombre del elemento (IE tiene una fuerte tolerancia a fallas, obtendrá una matriz, incluida la identificación igual al valor del nombre) getElementById()
/ /A través del elemento Id, sexo único

La relación entre BOM y DOM.

El nombre completo de BOM es Browser Object Model, que es el modelo de objetos del navegador, que se ocupa principalmente de ventanas y marcos del navegador.

El nombre completo de DOM es Document Object Model, que es la interfaz de programación de aplicaciones (API) de HTML y XML, sigue el estándar W3C y es un estándar que cumplen todos los navegadores.

JS accede, controla y modifica el cliente (navegador) accediendo al objeto BOM (Browser Object Model). Dado que la ventana de BOM contiene el documento, las propiedades y métodos del objeto de ventana se pueden usar y percibir directamente, por lo que puede ser directamente Usando el atributo de documento del objeto de ventana, puede acceder, recuperar y modificar el contenido y la estructura del documento XHTML a través del atributo de documento. Porque el objeto del documento es el nodo raíz del DOM.

Se puede decir que BOM contiene DOM (objeto), lo que el navegador proporciona para el acceso es el objeto BOM, desde el objeto BOM hasta el objeto DOM, js puede operar el navegador y los documentos leídos por el navegador.

¿Cuáles son los métodos nativos de los objetos de matriz? Vamos a enumerarlos.

pop、push、shift、unshift、splice、reverse、sort、concat、join、slice、toString、indexOf、lastIndexOf、reduce、reduceRight、forEach、map、filter、every、some

pop: elimina y devuelve el último elemento de la matriz (cambia la matriz original);
push: devuelve la longitud de la matriz después de la adición (cambia la matriz original);
shift: elimina y devuelve el primer elemento de la matriz (cambia el original matriz);
unshift: inserta un elemento segmento al principio de la matriz
: segmento (subíndice, número) devuelve la matriz recortada (sin cambiar la matriz original);
empalme: inserta, elimina o reemplaza elementos de la matriz
concat: fusiona las matrices y devuelve la matriz combinada (sin cambiar la matriz original) matriz original);
unirse: vincula la matriz en una cadena usando identificadores y devuelve la cadena empalmada (sin cambiar la matriz original);
inversa: voltea la matriz (cambia la matriz original) array);
toString: convierte la matriz en una cadena;
split: divide la cadena y la almacena en una matriz;
forEach: se usa principalmente para atravesar la matriz;
cada: se usa principalmente para verificar si cada elemento de la matriz cumple con las condiciones de la función, si uno de ellos no cumple con las condiciones, devuelve falso;
indexOf: se utiliza principalmente para buscar elementos en una matriz y devolver la posición del elemento.

Métodos de cadena

charAt(): encuentra el valor correspondiente según el subíndice

charCodeAt (): encuentra la codificación Unicode del carácter correspondiente a través del valor del subíndice

indexOf(): Encuentra el subíndice correspondiente por carácter (primera aparición)

lastIndexOf(): encuentra el último valor de subíndice que aparece a través de caracteres

rebanada(): cadena de intersección, 2 parámetros, (posición inicial, posición final)

split(): divide la cadena en matrices según el delimitador

substring(): intercepta la cadena, (posición inicial, posición final)

substr(): intercepta la cadena en la posición y longitud especificadas, (posición inicial, longitud)

toLowerCase(): convierte cadena a minúsculas

toUpperCase(): convierte cadena a mayúsculas

trim(): elimina todos los espacios antes y después de la cadena

¿Cuál es la diferencia entre los métodos Array.splice() y Array.slice() en JS?

Sin más, veamos el primer ejemplo:

var arr=[0,1,2,3,4,5,6,7,8,9];//设置一个数组console.log(arr.slice(2,7));//2,3,4,5,6console.log(arr.splice(2,7));//2,3,4,5,6,7,8//由此我们简单推测数量两个函数参数的意义,slice(start,end)第一个参数表示开始位置,第二个表示截取到的位置(不包含该位置)splice(start,length)第一个参数开始位置,第二个参数截取长度

Entonces mira el segundo:

var x=y=[0,1,2,3,4,5,6,7,8,9]console.log(x.slice(2,5));//2,3,4console.log(x);[0,1,2,3,4,5,6,7,8,9]原数组并未改变//接下来用同样方式测试spliceconsole.log(y.splice(2,5));//2,3,4,5,6console.log(y);//[0,1,7,8,9]显示原数组中的数值被剔除掉了

Aunque cortar y empalmar son objetos de matriz de interceptación, todavía existen diferencias obvias entre ellos. El primer parámetro de corte y empalme en los parámetros de la función es la posición inicial de intercepción, y el segundo parámetro de corte es la posición final de intercepción (no incluido ). , y el segundo parámetro de empalme (que indica la longitud de la intercepción desde la posición inicial), el corte no cambiará la matriz original y el empalme eliminará directamente los datos interceptados en la matriz original.

¿Cómo agregar/eliminar dinámicamente propiedades de un objeto en JS?

Podemos usar object.property_name = value para agregar propiedades al objeto, y eliminar object.property_name se usa para eliminar propiedades.

Por ejemplo:​​​​​​​

let user = new Object();// adding a propertyuser.name='Anil';user.age  =25;console.log(user);delete user.age;console.log(user);

Carga diferida y precarga de imágenes

Precarga: New Image(); se usa comúnmente, configure su src para implementar la precarga y luego use el método onload para devolver el evento de finalización de la precarga. ​​​​​​​

function loadImage(url, callback){
   
       var img = new Image(); //创建一个Image对象,实现图片预下载    img.src = url;    if (img.complete){
   
            // 如果图片已经存在于浏览器缓存,直接调用回调函数        callback.call(img);        return; // 直接返回,不用再处理onload事件    }    img.onload = function (){
   
       //图片下载完毕时异步调用callback函数。    callback.call(img);//将回调函数的this替换为Image对象 ,如果你直接用img.width的时候,图片还没有完全下载下来    };}

Carga diferida: el objetivo principal es optimizar la interfaz del servidor, aliviar la presión sobre la interfaz del servidor y reducir la cantidad de solicitudes únicas o solicitudes retrasadas. Método de implementación:
1. El primero es la carga retrasada pura, utilizando setTimeOut y setInterval para retrasar la carga,
2. El segundo es la carga condicional, que inicia la descarga asincrónica solo cuando se cumplen ciertas condiciones o se activan ciertos eventos.
3. El tercer método es cargar el área visual, es decir, cargar solo el área que el usuario puede ver, esto se logra principalmente monitoreando la barra de desplazamiento, generalmente comenzará a cargarse a cierta distancia antes de que el usuario vea una imagen, lo que puede garantizar que el usuario pueda ver la imagen cuando la baje.

¿Qué es una devolución de llamada?

Una función de devolución de llamada es una función JS normal que se pasa a un método como parámetro u opción. Es una función que se ejecuta después de que otra función ha terminado de ejecutarse, por eso se llama devolución de llamada.

En JS, las funciones son objetos, por lo tanto, las funciones pueden aceptar funciones como parámetros y pueden ser devueltas por otras funciones.

¿Cuál es la diferencia entre objetos host y objetos nativos en JS?

Objetos de host: son objetos proporcionados por el entorno de ejecución. Esto significa que son diferentes en diferentes contextos. Por ejemplo, los navegadores contienen objetos como Windows, pero el entorno Node.js proporciona objetos como Node List.

Objetos nativos: son objetos integrados en JS. También se les llama objetos globales porque los objetos integrados no se ven afectados por el entorno de ejecución si se usa JS.

Mejora progresiva y degradación elegante.

Mejora progresiva: cree páginas para navegadores de versión baja para garantizar las funciones más básicas y luego mejore los efectos, interacciones, etc. para navegadores avanzados para lograr una mejor experiencia de usuario.

Degradación elegante: cree una funcionalidad completa desde el principio y luego hágala compatible con navegadores de versiones inferiores.

¿Trabajador web y socket web?

websocket: proporciona comunicación bidireccional full-duplex a través de una única conexión persistente. Al utilizar protocolos personalizados (ws://, wss://), la política del mismo origen no se aplica a los sockets web.
trabajador web: JavaScript que se ejecuta en segundo plano y no afecta el rendimiento de la página.

Crear un trabajador: var trabajador = new Trabajador(url);
Enviar datos al trabajador: trabajador.postMessage(datos);
Recibir datos devueltos por el trabajador: trabajador.onmessage
Terminar la ejecución de un trabajador: trabajador.terminate();

hilo del navegador

Hilo del motor JS: interpreta y ejecuta código JS, entradas del usuario, solicitudes de red, etc.

Hilo GUI (hilo de renderizado): dibuja la interfaz de usuario y es mutuamente excluyente con el hilo principal JS

Hilo de solicitud de red HTTP: maneja las solicitudes GET, POST y otras del usuario, y después de obtener el resultado devuelto, envía la función de devolución de llamada a la cola de eventos

Hilo de activación del temporizador: setTimeout, setInterval espera el final del tiempo y envía la función de ejecución a la cola de eventos.

Hilo de procesamiento de eventos: después de que ocurren eventos interactivos como clic, mouse y entrada, la función de procesamiento de eventos se envía a la cola de eventos.

mecanismo de ejecución js, bucle de eventos

Una característica importante del lenguaje JavaScript es que tiene un solo subproceso y solo puede hacer una cosa a la vez. Un solo hilo significa que todas las tareas deben ponerse en cola y la siguiente tarea no se ejecutará hasta que se complete la tarea anterior. Si la tarea anterior lleva mucho tiempo, la siguiente tendrá que esperar.

Los diseñadores del lenguaje JavaScript se dieron cuenta de este problema y dividieron todas las tareas en dos tipos, una es tarea sincrónica (sincrónica) y la otra es tarea asincrónica (asincrónica). Antes de que se ejecuten todas las tareas sincrónicas, ninguna tarea asincrónica no se ejecutará. ser implementado.

Cuando abrimos un sitio web, el proceso de representación de la página web consta de muchas tareas sincronizadas, como la representación del esqueleto de la página y los elementos de la página. Las tareas que consumen muchos recursos y llevan mucho tiempo, como cargar imágenes y música, son tareas asincrónicas.

JS asincrónico tiene un mecanismo, que es ejecutar primero la macrotarea y colocar la macrotarea en la cola de eventos cuando se encuentra una macrotarea, y luego ejecutar la microtarea y colocar la microtarea en la cola de eventos. Sin embargo, estas dos colas no son una cola.

Cuando lo saque, primero obtenga la función de devolución de llamada de la microtarea y luego obtenga la función de devolución de llamada de la macrotarea de la cola de la macrotarea.

Tarea macro: secuencia de comandos de código general, setTimeout, setInterval
Microtarea: Promesa, proceso.nextTick

¿Por qué JS distingue entre microtareas y macrotareas?

(1) js tiene un solo subproceso, pero se divide en sincrónico y asincrónico
(2) Las microtareas y macrotareas son tareas asincrónicas y todas pertenecen a una cola
(3) Las macrotareas generalmente son: script, setTimeout, setInterval, setImmediate
(4) Microtareas: Promesa nativa
(5) Cuando encuentre una microtarea, ejecútela primero. Después de la ejecución, si no hay una microtarea, ejecute la siguiente macrotarea. Si hay microtareas, ejecútelas una por una en orden.

Formas de reducir el tiempo de carga de la página

  • Optimizar imágenes

  • Selección de formato de imagen (GIF: proporciona menos colores y se puede utilizar en lugares donde los requisitos de color no son altos)

  • Optimice CSS (comprima y combine CSS, como margen superior, margen izquierdo...)

  • Agregue una barra diagonal después de la URL (como www.campr.com/directorio, determinará qué tipo de archivo es este "directorio", o si es un directorio).

  • Indique el alto y el ancho (si el navegador no encuentra estos dos parámetros, debe calcular el tamaño mientras descarga la imagen. Si hay muchas imágenes, el navegador debe ajustar constantemente la página. Esto no solo afecta la velocidad, sino también afecta la experiencia de navegación. Cuando el navegador sabe Después de configurar los parámetros de alto y ancho, incluso si la imagen no se puede mostrar temporalmente, el espacio para la imagen quedará vacante en la página y luego el contenido posterior continuará cargándose. Como resultado, el tiempo de carga será más rápido y la experiencia de navegación será mejor).

  • Reduzca las solicitudes http (combinar archivos, combinar imágenes).

La diferencia entre hilos y procesos.

Un programa tiene al menos un proceso y un proceso tiene al menos un subproceso. La escala de división de subprocesos es menor que la de los procesos, lo que hace que los programas multiproceso sean altamente concurrentes.

Además, el proceso tiene una unidad de memoria independiente durante la ejecución y varios subprocesos comparten memoria, lo que mejora en gran medida la eficiencia de ejecución del programa.

Los subprocesos siguen siendo diferentes de los procesos durante la ejecución. Cada hilo independiente tiene un punto de entrada para la ejecución del programa, una secuencia de ejecución secuencial y un punto de salida para el programa.

Sin embargo, los subprocesos no se pueden ejecutar de forma independiente y deben existir en el programa de aplicación, y el programa de aplicación proporciona control de ejecución de múltiples subprocesos.

Desde un punto de vista lógico, el significado de subprocesos múltiples es que en una aplicación, se pueden ejecutar múltiples partes de ejecución al mismo tiempo. Sin embargo, el sistema operativo no considera múltiples subprocesos como múltiples aplicaciones independientes para implementar la programación, gestión y asignación de recursos de procesos. Ésta es la diferencia importante entre procesos y subprocesos.

¿Cuéntame sobre tu comprensión de la semántica?

1. Cuando se elimina o se pierde el estilo, la página puede presentar una estructura clara: HTML en sí no tiene rendimiento. Vemos que, por ejemplo, <h1> está en negrita, el tamaño de fuente es 2 em, negrita; <strong> está en negrita, no No creo que este sea el rendimiento de HTML. De hecho, los estilos CSS predeterminados de HTML están funcionando.

Por lo tanto, cuando el estilo se elimina o se pierde, la estructura clara de la página no es una ventaja de la estructura semántica HTML. Sin embargo, los navegadores tienen estilos predeterminados. El propósito del estilo predeterminado es expresar mejor la semántica de HTML. Puede Se puede decir que los navegadores Los estilos predeterminados y la estructura HTML semántica son inseparables.

2. Los lectores de pantalla (si el visitante tiene discapacidad visual) "leerán" su página basándose completamente en su marcado.

3. Es posible que dispositivos como PDA y teléfonos móviles no puedan representar páginas web como los navegadores de computadora comunes (generalmente porque estos dispositivos tienen un soporte débil para CSS).

4. Propicio para el SEO: establecer una buena comunicación con los motores de búsqueda ayuda a los rastreadores a rastrear información más eficaz: los rastreadores se basan en etiquetas para determinar el contexto y el peso de cada palabra clave.

5. Es más fácil para el desarrollo y mantenimiento del equipo y la semántica es más legible. Esta es una tendencia importante en el siguiente paso de las páginas web. Todos los equipos que siguen los estándares del W3C siguen este estándar, lo que puede reducir la diferenciación.

¿Por qué es más eficiente utilizar varios nombres de dominio para ofrecer recursos del sitio web?

1. El almacenamiento en caché de CDN es más conveniente

2. Superar el límite de concurrencia del navegador (generalmente no se establecen más de 6 enlaces por nombre de dominio)

3. Sin cookies, se ahorra ancho de banda, especialmente el ancho de banda de enlace ascendente es generalmente más lento que el ancho de banda de enlace descendente.

4. Aislar el contenido UGC del sitio principal para evitar problemas de seguridad innecesarios (cargar js para robar las cookies del sitio principal, etc.). Es por esta razón que el nombre de dominio del contenido del usuario no debe ser un nombre de subdominio del propio sitio principal, sino un nombre de dominio de un tercero completamente independiente.

5. Los datos se dividen e incluso se dividen en diferentes grupos físicos, y es más fácil desviar los datos a través de nombres de subdominio. Es posible que esto no se use mucho.

PD: Respecto al tema de las cookies, el ancho de banda es secundario, el aislamiento de seguridad es primario. Con respecto a varios nombres de dominio, más no siempre es mejor. Aunque el servidor puede realizar una interpretación general, al navegador le lleva mucho tiempo realizar la interpretación dns y hay demasiados nombres de dominio. Si desea utilizar https, todavía tiene para comprar más certificados e implementarlos.

¿Cómo organizas y optimizas tu código?

Interno: modo módulo; externo: herencia

reutilización de código

Evite las variables globales (espacio de nombres, espacio cerrado, mvc modular...)

Funciones divididas para evitar funciones infladas

Comentario

Modularización y componenteización del front-end

Modularización: reutilizable, centrándose en la encapsulación funcional, principalmente para código Javascript, aislando y organizando el código JavaScript copiado y encapsulándolo en módulos con funciones específicas.

Componentización: reutilizable, se presta más atención a la parte de la interfaz de usuario. Cada componente de la página, como el encabezado, el cuadro emergente e incluso el botón de confirmación, puede convertirse en un componente. Cada componente tiene códigos HTML, CSS y JS independientes. .

¿Mecanismo y función de caché HTTP?

Definición: el almacenamiento en caché del navegador sirve para acelerar la navegación. El navegador almacena los documentos solicitados recientemente en el disco del usuario. Cuando el visitante solicita esta página nuevamente, el navegador puede mostrar el documento desde el disco local, de modo que puede acelerar la lectura de la página.
La función del caché:
1. Reducir los retrasos, hacer que su sitio web sea más rápido y mejorar la experiencia del usuario.
2. Evite la congestión de la red, reduzca el volumen de solicitudes y reduzca el ancho de banda de salida.
Medios de implementación:
max-age en Cache-Control es el medio principal para implementar el caché de contenido. Hay tres estrategias comunes: la combinación de max-age y Last-Modified (If-Modified-Since), solo max-age, max- combinación de edad y ETag.

Para el almacenamiento en caché forzado, el servidor notifica al navegador un tiempo de caché. Durante el tiempo de caché, la siguiente solicitud utilizará directamente el caché. Si no está dentro del tiempo, se ejecutará una política de caché de comparación.
Para el almacenamiento en caché de comparación, la información Etag y Última modificación en el caché se envía al servidor a través de la solicitud y el servidor los verifica. Cuando se devuelve un código de estado 304, el navegador usa directamente el caché.

Códigos de estado HTTP comunes

400 La solicitud del cliente tiene un error de sintaxis y el servidor no la puede entender.
403 El servidor recibe la solicitud pero se niega a proporcionar el servicio. | 200 .exitosa
La solicitud del cliente es


¿Cuáles son los principales tipos de errores en JS?

Hay tres tipos de errores en JS:

Errores de tiempo de carga: los errores (como los errores de sintaxis) que ocurren al cargar una página web se denominan errores de tiempo de carga y generan errores de forma dinámica.

Errores de ejecución: Errores causados ​​por un mal uso de comandos en lenguaje html.

Errores lógicos: estos errores se deben a la ejecución de una lógica incorrecta en funciones con diferentes operaciones.

Enumere algunos patrones de diseño en JS

Los patrones de diseño son soluciones generales reutilizables a problemas comunes en el diseño de software. A continuación se muestran algunos patrones de diseño:

Patrón de creación: este patrón abstrae el proceso de creación de instancias del objeto.

Patrones estructurales: estos patrones tratan con diferentes clases y objetos para proporcionar nueva funcionalidad.

Modelo de comportamiento: también llamado modelo de publicación-suscripción, define una relación de objeto de uno a muchos entre un observador y varios observadores.

Patrones de diseño paralelo: estos patrones tratan con paradigmas de programación multiproceso.

Patrones de diseño arquitectónico: estos patrones se utilizan para abordar el diseño arquitectónico.

Nuevas características de es6

  1. constante dejar

  2. cadena de plantilla

  3. función de flecha

  4. Valores predeterminados de los parámetros de función

  5. Desestructuración de objetos y matrices.

  6. para...de 和 para...en

Explica qué es una función de flecha.

Las funciones de flecha son una forma concisa de escribir expresiones de funciones en ES6 o superior. Las funciones de flecha no se pueden usar como constructores y no admiten las palabras clave this, arguments, super o new.target. Son más adecuadas para funciones que no son de método. 

Normalmente, las funciones de flecha se ven así const function_name = () => {}. ​​​​​​

const greet=()=>{console.log('hello');}greet();

La diferencia entre funciones ordinarias y funciones de flecha.

1. Las funciones ordinarias
pueden cambiar este puntero mediante vinculación, llamada y aplicación.
Se puede usar New
. 2. La función de flecha
en sí no tiene este puntero.
Esto
se hereda de la función ordinaria que hereda esto de la primera función ordinaria en el capa externa cuando está definida. Cuando este punto de la función de flecha cambia, este punto de la función de flecha cambiará en consecuencia.
Cuando no hay una función ordinaria en la capa externa de la función de flecha, este punto de la ventana no puede
se puede cambiar mediante bind, call y apply. Llamar
a la función de flecha con new informará un error porque la función de flecha no tiene un constructor.

Explica qué es una promesa.

Una promesa es un objeto en js que se utiliza para generar un valor que puede producir resultados en el futuro. El valor puede ser un valor analizado o un motivo por el cual no se analizó el valor.

Una promesa puede tener tres estados:

pendiente: estado inicial, ni éxito ni fracaso
cumplido: significa que la operación fue completamente exitosa
rechazado: significa que la operación falló

Un objeto de promesa en estado de espera puede devolver un valor después del éxito o un error después del fracaso. Cuando ocurren estas dos situaciones, la función de procesamiento se pondrá en cola para su ejecución y luego se llamará al método.

resolver y rechazar son dos funciones respectivamente. Cuando se llama en la devolución de llamada, el estado de la instancia de promesa cambiará. resolver cambia el estado a éxito y rechazar a fracaso.

promesa escrita a mano 

function Promise(exector) {
   
     let _this = this;  //status表示一种状态  let status = “pending“;  let value = undefined;  let reason = undefined;  //成功  function resolve(value) {
   
       if (status == “pending“) {
   
         _this.value = value;      _this.status = “resolve“;    }  }  //执行失败  function reject(value) {
   
       if (status == “pending“) {
   
         _this.value = value;      _this.status = “reject“    }  }  //异步操作  try {
   
       exector(resolve, reject)  } catch (e) {
   
       reject(e)  }  //测试then  Promise.prototype.then = function(reject, resolve) {
   
       let _this = this;    if (this.status == “resolve“) {
   
         reject(_this.value)    }    if (this.status == “reject“) {
   
         resolve(_this.reason)    }  }} //new Promise测试let promise = new Promise((reject,resolve)=>{
   
       resolve(“return resolve“);});promise.then(data => {
   
     console.log(`success${data}`);}, err => {
   
     console.log(`err${data}`);})

¿Cuál es la diferencia entre promesa y asíncrono?

1. ¿Qué es Async/Await?
Async/await es una nueva forma de escribir código asincrónico. La forma en que se usa parece que
el async/await sincrónico se implementa en base a Promise. No se puede usar para funciones de devolución de llamada ordinarias.
2. ¿Qué es la promesa?
Se creó para resolver el anidamiento asincrónico y hacer que el código sea más fácil de entender.
La diferencia: async/await hace que el código sea más sincrónico y lo optimiza aún más.

Introducir varias soluciones asincrónicas.

(1) Función de devolución de llamada (devolución de llamada asincrónica)

Una devolución de llamada es una función que se pasa como parámetro a otra función y luego se ejecuta una vez que esa función ha terminado de ejecutarse.

(2) promesa 

El objeto de promesa es una especificación y un patrón propuestos por el grupo de trabajo commonJS para proporcionar una interfaz unificada para la programación asincrónica.

(3) asíncrono/espera

(4) Monitoreo de eventos

Adopte un modelo basado en eventos. La ejecución de una tarea no depende del orden del código, sino de si ocurre un evento.

(5) Publicar/Suscribirse

¿Cuál es la diferencia entre module.exports y exports?

El módulo y las exportaciones son dos objetos integrados en cada archivo js por Node.js. Se puede imprimir a través de console.log(módulo) y console.log(exportaciones). Si escribe las siguientes dos líneas en main.js y luego ejecuta $ node main.js:​​​​​​​

console.log(exports);//输出:{}console.log(module);//输出:Module {..., exports: {}, ...} (注:...代表省略了其他一些属性)

Al imprimir, podemos ver que module.exports y exports son objetos vacíos {} al principio, de hecho, estos dos objetos apuntan a la misma memoria. Esto significa que module.exports y exports son equivalentes (hay una premisa: no cambiar las direcciones de memoria a las que apuntan).

Por ejemplo: exports.age = 18 y module.export.age = 18, estos dos métodos de escritura son consistentes (ambos equivalen a agregar un atributo al objeto vacío original {}, y el resultado obtenido a través de require es {age: 18 }) .

¿Qué son las importaciones y exportaciones?

Las importaciones y exportaciones nos ayudan a escribir código JS modular. Usando importación y exportación, podemos dividir el código en varios archivos. La importación solo permite el acceso a ciertas variables o métodos específicos del archivo. Se pueden importar métodos o variables exportados por un módulo. ​​​​​​​

 //index.js import name,age from './person';  console.log(name); console.log(age);
 //person.js let name ='Sharad', occupation='developer', age =26; export { name, age}; ​​​​​​​

Enlace original: Preguntas básicas de la entrevista de preguntas de la entrevista de JavaScript (con respuestas)

 

Supongo que te gusta

Origin blog.csdn.net/weixin_64948861/article/details/129271915
Recomendado
Clasificación