Perguntas da entrevista de alta frequência em javaScript de front-end - atualização contínua

Índice

1. A diferença entre == e ===, em que situações são utilizadas?

2. Métodos para determinar o tipo de dados

3. Fale sobre os tipos de dados em JavaScript? Diferença de armazenamento?

4.Operadores em JavaScript

5.var,deixe,const

 6. A diferença entre cópia profunda e cópia superficial e o método de implementação

7. Anti-vibração e estrangulamento

8.A diferença entre setTimeout() e setInterval()

9. Objeto matemático

10.Qual é a diferença entre cookies, sessionStorage e localStorage?

 11. A diferença entre obter e postar

12.http e https 

13. Etapas básicas do ajax e os cinco estados do readyState e os princípios do ajax

 14.Quais são as formas de carregamento lento de JS?

15. Qual é a diferença entre nulo e indefinido?

16.js macro tarefas e micro tarefas

17. Método de operação de array

18. Métodos de string 

19. Por que 0,1+0,2 !== 0,3 e como torná-lo igual 

20.Como obter um valor indefinido seguro?

21.Qual é o resultado de typeof NaN?

 22. Qual é a diferença entre Object.is() e os operadores de comparação "===" e "=="?

23.As propriedades dos objetos const podem ser modificadas?

24. O que acontecerá se new for uma função de seta?

25. A diferença entre funções de seta e funções comuns

26. Princípio de implementação do novo operador

 27. Por que os argumentos da função são um pseudo array em vez de um array? Como iterar em um pseudo array?

28. Compreendendo o AJAX e implementando uma solicitação AJAX

29.Qual é a diferença entre os métodos forEach e map? 

30. Compreensão da Promessa

31. Fale sobre a diferença entre atributos defer e async em tags de script.

32. Conte-me sobre sua compreensão do encerramento.

33. Por favor, explique o mecanismo de bolha de eventos

34. Métodos para evitar o surgimento de eventos 

 35.O que é delegação de eventos? Quais são seus benefícios?

36. Remova aleatoriamente um valor do array

37.Javascript proíbe o navegador de retornar à página anterior

38. Terminal móvel Jquery proíbe zoom do navegador 

39. Como percorrer todas as propriedades de um objeto e exibir seus valores no console?

40. Como obter o tipo de dados de uma variável através de uma função?

41. Gere strings aleatórias

42. Gere números aleatórios dentro de um intervalo especificado

43. Existem muitas maneiras de formatar dinheiro, como estas duas maneiras.

44.Atualizando continuamente~~~


1. A diferença entre == e ===, em que situações são utilizadas?

operador igual

O operador igual é representado por dois sinais de igual (==). Se os operandos forem iguais, ele retornará true

Sabemos JavaScriptque existem conversões implícitas em . O operador igual (==) primeiro realizará a conversão de tipo durante a comparação e depois determinará se os operandos são iguais.

1. let result = (true == 1); // true    
如果任一操作数是布尔值,则将其转换为数值再比较是否相等

2. let result = ("55" == 55); // true    
如果一个操作数是字符串,另一个操作数是数值,则尝试将字符串转换为数值,再比较是否相等

3. let obj = {valueof:Function(){return 1}}
   let result = (obj == 1); // true
如果一个操作数是对象,另一个操作数不是,则调用对象的 valueOf() 方法取得其原始值,再根据前面的规则进行比较

    
4. let result = (null == undefined ); // true
null 和undefined相等

5. let result = (NaN == NaN ); // false
null 和undefined相等


6. let obj1 = {name:"xxx"}
let obj2 = {name:"xxx"}
let result = (obj1 == obj2 ); // false
如果两个操作数都是对象,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象,则相等操作符返回true

Resumo do operador igual :

  • Ambos são tipos simples. Strings e valores booleanos serão convertidos em valores numéricos e depois comparados.

  • Compare tipos simples com tipos de referência, converta o objeto em um valor de seu tipo original e compare

  • Se ambos forem tipos de referência, compare se apontam para o mesmo objeto.

  • nulo e indefinido são iguais

  • Se NaN existir, retorne falso

Operador de congruência 

O operador identidade é representado por três sinais de igual (===) e retorna apenas se os dois operandos forem iguais sem conversão  true. Ou seja, se os tipos forem iguais, os valores também deverão ser iguais.

1. let result1 = ("55" === 55); // false,不相等,因为数据类型不同
   let result2 = (55 === 55); // true,相等,因为数据类型相同值也相同
   
   undefined 和 null 与自身严格相等
2. let result1 = (null === null)  //true
   let result2 = (undefined === undefined)  //true

 Resumo dos operadores congruentes:

  • O operador de igualdade não realiza conversão de tipo

  • null e  undefined comparação, congruente comfalse

A diferença entre o operador de congruência e o operador igual

        O operador de igualdade (==) realizará a conversão de tipo e depois comparará os valores, enquanto o operador de congruência não realizará a conversão de tipo. 

2. Métodos para determinar o tipo de dados

1.typeOf 2.instanceof 3.object.prototype.toString.call 4.construtor 

//1.typeOf
let obj={
   name:'dawn',
   age:21
}
let fn=function() {
    console.log('我是 function 类型');
}
console.log(typeof 1);       //number
console.log(typeof 'abc');   //string
console.log(typeof true);    //boolean
console.log(typeof undefined);  //undefined 
console.log(typeof fn);      //function
console.log(typeof (new Date) );  //object
console.log(typeof null);     //object
console.log(typeof [1,2,3]);  //object
console.log(typeof obj);      //object
//由结果可知typeof可以测试出number、string、boolean、undefined及function。对于null及数组、对象,typeof均检测出为object,不能进一步判断它们的类型。



//2.instanceof
let arr=[1,2,3,4,5,6,7]
let obj={
   name:'dawn',
   age:21
}
let fn=function() {
   console.log('我是 function 类型');
}
console.log(arr instanceof Array);  //true
console.log(obj instanceof Object);  //true
console.log(fn instanceof Function);  //true
console.log((new Date) instanceof Date);  //true
//obj instanceof Object ,可以左边放你要判断的内容,右边放类型来进行JS类型判断,只能用来判断复杂数据类型,因为instanceof 是用于检测构造函数(右边)的 prototype 属性是否出现在某个实例对象(左边)的原型链上。




//3.Object.prototype.toString.call
let obj = {
   name: 'dawn',
   age: 21
}
let fn = function () {
   console.log('我是 function 类型');
}    
console.log(Object.prototype.toString.call(1));        // [object Number]   
console.log(Object.prototype.toString.call('Hello tomorrow')); // [object String ]
console.log(Object.prototype.toString.call(true));     // [object Boolean]
console.log(Object.prototype.toString.call(undefined));  // [object Undefined]
console.log(Object.prototype.toString.call(fn));   // [object Function]
console.log(Object.prototype.toString.call(new Date));  // [object Date]
console.log(Object.prototype.toString.call(null));   // [object Null]
console.log(Object.prototype.toString.call([1, 2, 3]));  // [object Array]
console.log(Object.prototype.toString.call(obj));       // [object Object]
//在任何值上调用 Object 原生的 toString() 方法,都会返回一个 [object NativeConstructorName] 格式的字符串。每个类在内部都有一个 [[Class]] 属性,这个属性中就指定了上述字符串中的构造函数名。
但是它不能检测非原生构造函数的构造函数名。



//4.constructor
let arr = [1, 2, 3, 4, 5, 6, 7]
let obj = {
   name: 'dawn',
   age: 21
}
let fn = function () {
   console.log('我是 function 类型');
} 
console.log((9).constructor === Number);  //true
console.log('hello'.constructor === String);  //true
console.log(true.constructor === Boolean);  //true
console.log(fn.constructor === Function);  //true
console.log((new Date).constructor === Date);  //true
console.log(obj.constructor === Object);  //true
console.log([1, 2, 3].constructor === Array);  //true
//constructor不能判断undefined和null,并且使用它是不安全的,因为contructor的指向是可以改变的

3. Fale sobre os tipos de dados em JavaScript? Diferença de armazenamento?

Os tipos de dados em JavaScript são divididos em:

        Tipos de dados básicos: Número, String, Booleano, Indefinido, Nulo, Símbolo

        Tipos de dados complexos: Objeto, Matriz, Função, Data, RegExp,...etc.

Diferença de armazenamento:

        Tipos de dados básicos são armazenados na pilha

        Objetos de tipo de referência são armazenados no heap

//1.基本类型
let a = 10;
let b = a; // 赋值操作
b = 20;
console.log(a); // 10值
//a的值为一个基本类型,是存储在栈中,将a的值赋给b,虽然两个变量的值相等,但是两个变量保存了两个不同的内存地址


//2.引用类型
var obj1 = {}
var obj2 = obj1;
obj2.name = "Xxx";
console.log(obj1.name); // xxx
//引用类型数据存放在内对内中,每个堆内存中有一个引用地址,该引用地址存放在栈中obj1是一个引用类型,在赋值操作过程汇总,实际是将堆内存对象在栈内存的引用地址复制了一份给了obj2,实际上他们共同指向了同一个堆内存对象,所以更改obj2会对obj1产生影响

 Resumir:

  • Diferentes alocações de endereços de memória ao declarar variáveis:
    • Valores de tipos simples são armazenados na pilha e os valores correspondentes são armazenados na pilha
    • O valor correspondente ao tipo de referência é armazenado no heap, e o endereço que aponta para a memória heap é armazenado na pilha
  • Diferentes tipos de dados levam a diferenças na atribuição de variáveis:
    • A atribuição de tipo simples consiste em gerar o mesmo valor e dois objetos correspondem a endereços diferentes
    • A atribuição de tipo complexo consiste em atribuir o endereço de memória do objeto salvo a outra variável. Ou seja, as duas variáveis ​​apontam para o mesmo objeto na memória heap.

4.Operadores em JavaScript

//1.递增递减操作符
//使用++、--两种符号表示递增和递减,同时根据符号位置的不同,又分为前置递增递减和后置递增递减:
var num1 = 10;
var n = ++num1; // 前置递增,先执行递增计算,再对n进行赋值,所以,n=11,num1=11
var num2 = 10;
var m = --num2; // 前置递减,先执行递减计算,再对m进行赋值,所以,m=9,num2=9
var x = num2++; // 后置递增,先赋值,再执行递增计算,所以,x=9,num2=10;


//2.一元加、一元减操作符
//+表示一元加操作符,-表示一元减操作符,这两种操作符放在数值前面,相当于属数学中的正负号。
var a = 10;
console.log(-a); // -10
console.log(+a); // 10


//3.布尔操作符
//布尔操作符有三个:与、或、非
//&& 逻辑与    两边都是true,才返回true,否则返回false
//|| 逻辑或    两边只要有一个是true,就返回true,否则返回false
//! 逻辑非   用来取一个布尔值相反的值  
{} && false; // false
false && {}; // {}
{na:1} && {na:2}; // {na:2}
null && false; // null
NaN && false; // NaN
undefined && false; // undefined

{} || false; // {}
1 === 2 || false; // false
{n:1} || {n:2}; // {n:1}
null || null; // null
NaN || NaN; // NaN
undefined || undefined; // undefined 

//在进行||、&&操作时,如果有一个操作数不是布尔值,返回结果也不一定是布尔值:

5.var,deixe,const

  1. Variáveis ​​definidas por var podem ser pré-analisadas e o resultado da chamada antecipada é indefinido. Variáveis ​​definidas por let não podem ser pré-analisadas. O resultado da chamada antecipada é um erro ( ReferenceError ) . Variáveis ​​definidas por const não podem ser pré-analisadas e o resultado da chamada antecipada é um erro.
  2. Para variáveis ​​definidas por var, o nome da variável pode ser repetido, e o efeito é a atribuição repetida.As variáveis ​​definidas por let não podem ser repetidas, caso contrário, um erro será relatado durante a execução. As variáveis ​​definidas por const não podem ser repetidas, caso contrário um erro será reportado durante a execução.
  3. O escopo da variável definido por var é o escopo global/local. Variáveis ​​definidas por let só poderão ser chamadas em {} se estiverem em {}.
  4. Variáveis ​​de loop definidas por var na instrução de loop e variáveis ​​de loop definidas usando let. Os princípios de execução e os efeitos de execução são diferentes.
  5. Os valores dos dados armazenados em variáveis ​​definidas por const não podem ser alterados, ou seja, variáveis ​​definidas por const não podem receber valores repetidamente.
//提前使用
console.log(a)    //提前调用 预解析
console.log(b)   //报错
var a = 1
let b = 2

//const与let 定义的变量不能重复
var init = 11
var init = 22
let init2 = 11
let init2 = 22
console.log(init)   //22  var声明的变量被重新赋值
consoloe.log(init2) //会报错

//const与let 定义的变量如果在{}中那么只能在{}中来使用
if (true) {
  var a = 300;
  let b = 400;
  const c = 500;
  // let 声明的变量 在 { } 中可以调用
  console.log(b);
  console.log(c);
}
console.log(a);   //300
// let和const 声明的变量 在 { } 外 不能调用 
console.log(c);  //报错
console.log(b);  //报错


//const定义的变量 不能重复赋值
const aa = 100
aa = 200
console.log(aa)  //报错

const a = {
    name: 'zhang',
    age: '18'
}
console.log(a.name)//zhang
a.name = 'zhen';
console.log(a.name)//zhen

const b = [1, 2, 3, 4, 5]
console.log(b[0])//1
b[0] = 0;
console.log(b[0])//0
//const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。

questões do exame

        Qual é a entrada do código a seguir?

                

        function digaOi() {

                console.log(nome);

                console.log(idade);

                var nome = "Xiong Da";

                deixe idade = 18;

        }

A: Urso grande  undefined  B: Urso grande  ReferenceError  C:  ReferenceError E 18   D:  undefined E ReferenceError

A resposta é: D. Como você realmente entende isso?

 6. A diferença entre cópia profunda e cópia superficial e o método de implementação

Cópia superficial:

        Atribuir a referência do objeto original ou do array original diretamente ao novo objeto, o novo array, o novo objeto é apenas uma referência ao objeto original, sem copiar o próprio objeto, e os objetos antigos e novos ainda compartilham a mesma memória

        Se o atributo for um tipo de dados básico, o valor copiado será do tipo básico. Se o atributo for um tipo de referência, o endereço de memória será copiado.

Cópia profunda:

        Crie um novo objeto e array e copie o "valor" (todos os elementos do array) dos atributos do objeto original, que é "valor" em vez de "referência"

        Cópia profunda consiste em copiar completamente um objeto da memória, abrir uma nova área da memória heap para armazenar o novo objeto e modificar o novo objeto sem afetar o objeto original

Método de cópia superficial:

        atribuição direta de objeto

        Objeto.atribuir

Método de cópia profunda:

        JSON.stringify para string e JSON.parse para objeto

        Travessia recursiva profunda

        Escreva uma solução recursiva (recomendada e relativamente perfeita) para encapsular uma função de cópia profunda do DeepClone

//浅拷贝
//1.直接对象赋值
let a = [0,1,2,3,4];
b = a;
console.log(a === b);
a[0] = 1;
console.log(a, b) // a=11234  b=11234

//2. 解构赋值
var obj1 = {a: 1, b: 2}
var obj2 = {...obj1}
obj2.a = 4
console.log(obj1, obj2) //obj1 = {a:1,b:2}   obj2 = {a:4,b:2}

//3.Object.assign()
let obj1 = { 
	a: { b: 1}, 
	c: 2
}
let obj2 = Object.assign({},obj1)
obj2.a.b = 3;  //第二层,obj1变了,是浅拷贝
obj2.c = 3;  //第一层,obj1不变,是深拷贝
console.log(obj1);  //{a:{b:3},c:2}
console.log(obj2);  //{a:{b:3},c:3}
//严格来说,Object.assign() 既不是深拷贝,也不是浅拷贝——而是第一级属性深拷贝,第一级以下的级别属性浅拷贝。

//深拷贝
//1.封装deepClone深拷贝的方法
function DeepClone(data) {
  const newData = Array.isArray(data) ? [] : {}
  for (let key in data) {
    if (data[key] && typeof data[key] === 'object') {
       newData[key] = DeepClone(data[key])
    } else {
      newData[key] = data[key]
    }
  }
  return newData
}
//调用他
const obj2 = DeepClone(obj1)

//2.JSON.stringify转为字符串再JSON.parse
//JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象
//缺点:当值为undefined、function、symbol 会在转换过程中被忽略

//3.jquery 提供一个 $.extend 可以用来做深拷贝;
var obj = {a:{name:"kaiqin",age:19}};
var obj1 = {b:{name:"wang",age:19}};
var obj2 = $.extend(true,{},obj,obj1); //true为深拷贝,false为浅拷贝,默认为false
obj2.a.name="zhang";
console.log(obj2)
//{a: {name: "zhang", age: 19},b: {name: "wang", age: 19}}
console.log(obj)
//{
   
   {a:{name:"kaiqin",age:19}}}

7. Anti-vibração e estrangulamento

Anti-vibração : Anti-vibração significa que após um evento ser acionado, a função só pode ser executada uma vez em n segundos. Se um evento for acionado novamente em n segundos, o tempo de execução da função será recalculado. DOM Ele pode ser usado para verificação de entrada em tempo real input.change e eventos window.resize.Por exemplo, após a conclusão do dimensionamento da janela, parte do tamanho será recalculado. 

Throttling : O chamado throttling significa que os eventos são acionados continuamente, mas a função só é executada uma vez em n segundos. Existem duas maneiras de conseguir isso, ou seja, a versão do carimbo de data/hora e a versão do temporizador . Usado para monitoramento  mousemove, rolagem do mouse e outros eventos, geralmente usado para: animação de arrastar, carregamento suspenso.

//防抖
//用定时器实现防抖
function debounce(fn, wait) {
    let timout = null;
    return function () {
        clearTimeout(timout)
        timout = setTimeout(fn, wait)
    }
}


//节流
//定时器实现节流
function throttle(func, wait) {
    var timer = null;
    return function () {
        var _this = this;
        var args = arguments;
        if (!timer) {
            timer = setTimeout(function () {
                timer = null;
                func.apply(_this, args)
            }, wait)
        }
    }
}

//时间戳实现节流
function throttle(func, wait) {
    //定义初始时间
    var oldTime = 0;
    return function () {
        var _this = this;
        var args = arguments;
        //当前时间戳
        var newTime = +new Date();
        //判断用当前时间减去旧的时间,如果大于wait指定的时间就会触发
        if (newTime - oldTime > wait) {
            //执行触发的函数
            func.apply(_this, args)
            //将旧时间更新
            oldTime = newTime;
        }

    }

8.A diferença entre setTimeout() e setInterval()

1. Nas mesmas condições, setTimeout() é executado apenas uma vez e setInterval() é executado em um loop ;
2. setTimeout() é executado uma vez com atraso: setTimeout(fn, 1000); //Atraso 1 segundo e executa fn() uma vez;
3. setInterval() executa em um loop em intervalos; setInterval(fn, 1000); //A cada 1 segundo, executa fn() em um loop

9. Objeto matemático

Math.PI                // 圆周率
Math.random()          // 生成随机数
Math.floor()           // 向下取整
Math.ceil()            //向上取整
Math.round()           // 取整,四舍五入
Math.abs()             // 绝对值
Math.max()             //求最大值
Math.min()             //求最小值
Math.sin()             // 正弦
Math.cos()             //余弦
Math.power()           // 求指数次幂
Math.sqrt()            //求平方根


//求10到20的随机数
//生成 min 到 max 之间的随机数
var min = 10;
var max = 20;
console.log( parseInt(Math.random() * (max - min) + min));

10.Qual é a diferença entre cookies, sessionStorage e localStorage?

Mesmo ponto:

        SessionStorage, LocalStorage e Cookie podem ser usados ​​para armazenar dados no lado do navegador e são todos pares de valores-chave do tipo string.

diferença:

        SessionStorage: O tamanho dos dados de armazenamento é de cerca de 5 M. Ele não participa da comunicação do servidor e será limpo quando a página ou navegador atual for fechado.

        localStorage: O tamanho dos dados de armazenamento é de aproximadamente 5M ou maior, não participa da comunicação do servidor e é permanentemente válido, a menos que seja excluído manualmente ou o código seja excluído.

        Cookies: pequenos dados de texto com tamanho aproximado de 4k, geralmente gerados pelo servidor. O tempo de expiração pode ser definido. Se não houver configuração, feche o navegador e ele irá expirar.

 11. A diferença entre obter e postar

  1. get geralmente é usado para obter solicitações e post geralmente é usado para enviar solicitações.
  2. Get tende a ser colocado na url e post tende a ser colocado no corpo.
  3. Fundamentalmente falando, ambos os métodos de solicitação não são seguros o suficiente, porque o próprio http é um protocolo de texto não criptografado, portanto, a prática comum de segurança é usar o protocolo de criptografia de chave https. Como get é colocado no corpo da solicitação, uma abordagem relativamente segura é usar a abordagem post+body.
  4. O limite de comprimento dos dados obtidos na verdade se refere ao limite de comprimento do URL, mas o protocolo http em si não impõe nenhum limite ao comprimento do URL. O limite real é limitado pelo cliente/navegador e pelo servidor.

12.http e https 

  1. O protocolo https exige a solicitação de um certificado da CA. Geralmente, há menos certificados gratuitos, portanto, é necessária uma determinada taxa.
  2. http é um protocolo de transferência de hipertexto e as informações são transmitidas em texto simples, enquanto https é um protocolo de transmissão criptografado SSL seguro.
  3. http e https usam métodos de conexão completamente diferentes e portas diferentes, o primeiro é 80 e o último é 443.
  4. A conexão http é muito simples e sem estado; o protocolo HTTPS é um protocolo de rede construído a partir do protocolo SSL+HTTP que pode realizar transmissão criptografada e autenticação de identidade, e é mais seguro que o protocolo http.

13. Etapas básicas do ajax e os cinco estados do readyState e os princípios do ajax

//1创建对象xmlhttprequest
const xhr = new XMLHTTPRequest();
//2创建一个http请求初始化
xhr.open('GET','/api',false);
//3send发送请求
xhr.send();
//4监听状态变化
xhr.onreadystatechange = function(){
 //5查看状态码判断状态
 if(xhr.readyState == 4){
   if(xhr.status >= 200 &&xhr.status <= 300){
   }
 }
}

Cinco estados de readyState:

  1. Não inicializado 0
  2. carregando 1
  3. carregamento completo 2
  4. Comece a analisar 3
  5. Análise concluída 4

O princípio do ajax:

        O princípio do ajax é que o navegador pede ao xhr (XmlHttpRequest) para solicitar dados ao servidor, e o navegador faz outras coisas.Quando o servidor retorna os dados para o xhr, o xhr notifica o navegador e o navegador renderiza os dados para a página .

 14.Quais são as formas de carregamento lento de JS?

<script defer type="text/javascript" src='script.js'></script>
//defer : 等html全部解析完成,才会执行js代码,顺次执行js脚本。

15. Qual é a diferença entre nulo e indefinido?

null é um objeto que representa "none" (ponteiro de objeto nulo), que é 0 quando convertido em um valor numérico;

indefinido é um valor primitivo que representa "none", que é NaN quando convertido em um valor numérico.

16.js macro tarefas e micro tarefas

As tarefas de macro js incluem: eventos setTimeout, setInterval, Ajax, DOM

As microtarefas js incluem: process.nextTick, Promise.then catch

 Quem executa primeiro as tarefas macro ou micro tarefas js?

        JS é de thread único. Se encontrar execução síncrona, será executado de forma síncrona até que a execução seja concluída. Se encontrar execução assíncrona, será colocado na fila de execução. Assincronia (macro tarefas e micro tarefas), micro tarefas são melhor do que tarefas macro em execução assíncrona.

setTimeout(() => {
  console.log(4);
})
new Promise(resolve => {
  resolve()
  console.log(1)
}).then(_ => {
  console.log(3)
})
console.log(2)

         setTimeout é assíncrono, portanto é ignorado e chega à sincronização dentro da execução do Promise, console.log(1) . O próximo é um assíncrono, ignorado. O último é um código de sincronização console.log(2). A próxima etapa é o código assíncrono que ignoramos antes. De cima para baixo, o primeiro é setTimeout e o outro é Promise.then().

        setTimeout é assíncrono para tarefas macro e Promise.then() é assíncrono para micro tarefas. As micro tarefas são executadas antes das tarefas macro. Portanto, neste momento, a tarefa setTimeout será ignorada primeiro e duas micro tarefas de Promise.then () será executado. Portanto, a função console.log(3) será executada neste momento. No final, resta apenas a função setTimeout para ser executada, então console.log(4) é finalmente executado.

        Análise resumida: Resultados da execução 1 2 3 4        

17. Método de operação de array

//数组的操作方法
    push() //1.从数组末尾追加
    unshift() //2.从数组前面添加
    pop() //3.从数组末尾删除
    shift() //4.从数组头部删除
    reverse() //5.数组反转
    sort() //6.数组排序
    splice() //7.删除 添加 替换
    //以上七种可以修改数组本身
    forEach() //8.循环遍历
    concat() //9.拼接数组
    filter() //10.过滤数组
    slice() //11.截取元素
    every() //12.判断数组中是否有满足
    some() //13.只要有一个满足条件返回值就是true,没有满足条件的则为false
    reduce() //14.数组求和
    indexO() //15.查找值  从前往后查找
    lastIndexOf() //16.查找值  是从后往前查找。
    toString() //17.把数组转换为字符串
    join() //18.把数组转换为字符串, 可以传入不同的符号进行连接 默认用逗号连接
    toLocaleString() //19.把数组转换为字符串
    map() //20.指“映射”,对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。返回新数组
    find() //21.返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。
    flat() //22.按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。此方法不会改变原数组。depth 可选 指定要提取嵌套数组的结构深度,默认值为 1。如果不确定嵌套多少层,可以使用ES10新增:BigInt 表示任意大的整数
    findIndex() //23.方法返回传入一个测试条件(函数)符合条件的数组第一个元素位置。
    Array.at()  //24.返回指定索引处的值。
    
//数组的操作方法
//1.push()从数组末尾追加
//push从数组末尾添加,返回值是数组的长度,会改变原数组
var arr = [1, 2, 3, 4, 5]
console.log(arr.push(6, 7));        // 7 arr数组的长度 
console.log(arr);                   //输出结果:[1, 2, 3, 4, 5, 6, 7]

//2.unshift()从数组前面添加
//unshift从数组前面添加,返回值是数组的长度,会改变原数组
var arr = [1, 2, 3, 4, 5]
console.log(arr.unshift(6, 7));        // 7 arr数组的长度 
console.log(arr);                      //输出结果:[ 6, 7, 1, 2, 3, 4, 5 ]

//3.pop()从数组末尾删除
//pop 从数组末尾删除,返回值是删除的值,会改变原数组
var arr = [1, 2, 3, 4, 5]
console.log(arr.pop());        // 5 删除的值
console.log(arr);              //输出结果:[ 1, 2, 3, 4 ]

//4.shift()从数组头部删除
//shift 从数组头部删除,返回值是删除的值,会改变原数组
var arr = [1, 2, 3, 4, 5]
console.log(arr.shift());        // 1 删除的值
console.log(arr);                //输出结果:[ 2, 3, 4,5 ]

//5.reverse()数组反转
//reverse数组反转,返回值是反转后的数组,会改变原数组
var arr = [1, 2, 3, 4, 5]
console.log(arr.reverse());        // [5, 4, 3, 2, 1]
console.log(arr);                  //输出结果:[5, 4, 3, 2, 1]

//6.sort()数组排序
//sort数组排序,返回值是排序后的数组,会改变原数组
var arr = [1, 2, 3, 4, 5, 9, 8, 7, 6]
console.log(arr.sort());           //[1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log(arr);                  //输出结果:[1, 2, 3, 4, 5, 6, 7, 8, 9]

//7.splice()删除 添加 替换
//splice(index,howmany,arr1,arr2),删除元素并添加元素,从index位置开始删除howmany个元素,
//并将arr1,arr2数据从index位置依次插入。howmany为0时,则不删除元素。
//splice数组排序,返回值是删除的数组,会改变原数组
var arr = [1, 2, 3, 4, 5]
console.log(arr.splice(0,2,111,222));           //[1, 2]
console.log(arr);                  //输出结果: [111, 222, 3, 4, 5]

//以上七种方法是修改原数组的

//8.forEach()循环遍历
//forEach循环遍历,没有返回值,回调函数的参数,第一个参数是数组的每一项,第二个参数是数组中每一项的下标,第三个参数是数组的本身。
var arr = [1, 2, 3, 4, 5]
arr.forEach((item,index,abc) => {console.log(item,index,abc)})

//9.concat()拼接数组
//用来拼接数组 并且 会返回一个新数组。
var arr = [1, 2, 3, 4, 5, 6];
console.log(arr.concat([7, 8, 9]));    //输出结果:[ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
var arr1 = [1, 2, 3, 4, 5, 6];
var arr2 = [7, 8, 9]
var arr3 = arr1.concat(arr2)
console.log(arr1);      //[ 1, 2, 3, 4, 5, 6 ]
console.log(arr3);      //输出结果:[ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

//10.filter()过滤数组
//filter返回值是一个新的数组,filter里面可以直接 return 筛选条件 
let arr = [20, 50, 80, 90]
let newArr = arr.filter((item, index, array) => {    
//item:数组每一项,index:数组每一项的x下标,array:数组本身
    return item >= 70
})
console.log(newArr);  //返回筛选后的数组 [ 80, 90 ]

//11.slice()截取元素
//slice( ):数组元素的截取,返回一个新数组,新数组是截取的元素,可以为负值。
//从数组中截取,如果不传参,会返回原数组。如果只传入一个参数,会从头部开始删除,直到数组结束,原数组不会改变;传入两个参数,第一个是开始截取的索引,第二个是结束截取的索引,不包含结束截取的这一项,原数组不会改变。最多可以接受两个参数。
let arr = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
console.log(arr.slice(0, 2));     // 返回值是被删除的元素['a','b']  
console.log(arr);                 //['a', 'b', 'c', 'd', 'e', 'f', 'g']

//12.every()判断数组中是否有满足
//every遍历数组  一般用于判断数组中是否有满足条件的数组元素,所有元素遍历之后,所有元素都满足条件的元素是返回值为true,若有一个不满足则返回false.
var arr = [1, 2, 3, 4, 5, 6]
console.log(arr.every(item => item > 1));     //输出结果:false
var arr = [1, 2, 3, 4, 5, 6]
console.log(arr.every(item => item > 0));     //输出结果:true

//13.some()只要有一个满足条件返回值就是true,没有满足条件的则为false
//some方法和every方法非常的类似 ,所有元素遍历之后,所有元素都满足条件的元素是返回值为true,若有一个不满足则返回false.
var arr = [1, 2, 3, 4, 5, 6]
console.log(arr.every(item => item > 6));     //输出结果:false
var arr = [1, 2, 3, 4, 5, 6]
console.log(arr.every(item => item > 3));     //输出结果:true

//14.reduce()数组求和
//1.reduce方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
​//2.reduce方法可以接收两个参数,第一个参数:要执行的函数,第二个参数:函数迭代的初始值
//3.第一个参数不是函数吗?函数里面的参数如下
    prev:上次调用函数的返回值
    cur:当前元素
    index:当前元素索引
    arr:被遍历的数组
//4.array.reduce(function(prev, currentValue, currentIndex, arr), initValue) //initValue是第二个参数
//不传入函数迭代的初始值
const arr = [11, 22, 33, 44]
const sum = arr.reduce((prev, cur, index) => {
   console.log(prev, cur, index);
   return prev + cur
})        //没有传入函数迭代的初始值, 初始值默认是数组第一位 , prev 就是计算结束后的返回值。
console.log('sum:', sum);   //110   
//传入函数迭代的初始值
const arr = [11, 22, 33, 44]
const sum = arr.reduce((prev, cur, index) => {
   console.log(prev, cur, index);
   return prev + cur
}, 10)    //传入函数迭代的初始值之后,也就是让 prev 从10开始累加,然后接着迭代累加 prev 
console.log('sum:', sum);    //120

//15.indexO()查找值  从前往后查找
//接受两个参数:查找的值、查找起始位置
//不存在,返回 -1 ;存在,返回位置。
var arr = [1, 2, 3, 4, 5]
console.log(arr.indexof(2,3))  //-1

//16.lastIndexOf()查找值  是从后往前查找。
//接受两个参数:查找的值、查找起始位置
//不存在,返回 -1 ;存在,返回位置。
var arr = [1, 2, 3, 4, 5]
console.log(arr.lastIndexOf(2,3))  //1

//17.toString()把数组转换为字符串
var arr = [1, 2, 3, 4, 5]
console.log(arr.toString())    //'1,2,3,4,5'

//18.join()把数组转换为字符串, 可以传入不同的符号进行连接 默认用逗号连接
var arr = [1, 2, 3, 4, 5]
console.log(arr.join('|'))    //'1|2|3|4|5'

//19.toLocaleString()把数组转换为字符串
var arr = [1, 2, 3, 4, 5]
console.log(arr.toLocaleString())    //'1,2,3,4,5'

//20.map()指“映射”,对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。返回新数组
var arr = [1, 2, 3, 4, 5];
var arr2 = arr.map(function(item){
return item*item;
});
console.log(arr2); //[1, 4, 9, 16, 25]

//21.find()
//返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。
// 获取数组中第一个大于10的值
const array1 = [5, 12, 8, 130, 44];
const found = array1.find(element => element > 10);
console.log(found);// expected output: 12

//22.flat()
//按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。此方法不会改变原数组。
//depth 可选 指定要提取嵌套数组的结构深度,默认值为 1。如果不确定嵌套多少层,可以使用ES10新增:BigInt 表示任意大的整数
const arr1 = [0, 1, 2, [3, 4]];
console.log(arr1.flat());// log: [0, 1, 2, 3, 4]
const arr2 = [0, 1, 2, [[[3, 4]]]];
console.log(arr2.flat(2));// log: [0, 1, 2, [3, 4]]

//23.findIndex()方法返回传入一个测试条件(函数)符合条件的数组第一个元素位置。
//IE 11 及更早版本不支持 findIndex() 方法
var arr2 = [1,18,2,99,666,44,66];
var flag2 = arr2.findIndex(item => {
   return item > 50;
});    //当数组中的元素在测试条件时返回 true 时, findIndex() 返回符合条件的元素的索引位置,如果没有符合条件的元素返回 -1
console.log(flag2)   // 得到: 3

//24.Array.at()返回指定索引处的值。
const list = [1, 2, 3, 4, 5];
list.at(1); // 2
list.at(-1); // 5
list.at(-2); // 4

18. Métodos de string 

//字符串常用方法
    charAt()        //1.返回在指定位置的字符
    charCodeAt()    //2.返回在指定的位置的字符的 Unicode 编码。
    concat()        //3.连接字符串。
    indexOf()       //4.检索字符串。indexOf() 方法对大小写敏感。
    match()         //5.是用来查找字符的 
    includes()      //6.判断字符串是否包含指定的子字符串。
    repeat()        //7.字符串复制指定次数
    replace()       //8.方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。
    replaceAll()    //9.字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串,该函数会替换所有匹配到的子字符串。
    search()        //10.方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串。返回与指定查找的字符串或者正则表达式相匹配的 String 对象起始位置。
    slice()         //11.提取字符串的某个部分,并以新的字符串返回被提取的部分。
    split()         //12.方法用于把一个字符串分割成字符串数组
    substring()     //13.方法用于提取字符串中介于两个指定下标之间的字符。
    toLowerCase()   //14.方法用于把字符串转换为小写。
    toUpperCase()   //15.方法用于把字符串转换为大写。
    trim()          //16.删除字符串的头尾空白符,空白符包括:空格、制表符 tab、换行符等其他空白符等
    includes(), startsWith(), endsWith()    //17.来确定一个字符串是否包含在另一个字符串中
    
//1.charAt()返回在指定位置的字符
var str="abc"
console.log(str.charAt(0))//a

//2.charCodeAt()返回在指定的位置的字符的 Unicode 编码。
var str="abc"
console.log(str.charCodeAt(1))//98

//3.concat()连接字符串。
var a = "abc";  
var b = "def";  
var c = a.concat(b);
console.log(c);//abcdef

//4.indexOf()检索字符串。indexOf() 方法对大小写敏感。
var str="Hello world!"
console.log(str.indexOf("Hello"))//0
console.log(str.indexOf("World"))//-1
console.log(str.indexOf("world"))///6

//5.match()是用来查找字符的 
//方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。该方法类似 indexOf() 和 lastIndexOf(),但是它返回指定的值,而不是字符串的位置
var str = 'asdfghajkwyai';
var result = str.match('a');   //result = a
//如果想查找所有满足的匹配结果,就要加一个 g 才会返回所有满足匹配的结果
var str = 'asdfghajkwyai';
var result = str.match(/a/g);    //result = aaa
//若没有标志 g,.match()方法就只执行一次匹配,找到结果就返回,不会接着去查找;若没有找到任何匹配文本,.match()方法将会返回nul;
//若有标志 g,.match()就会返回一个数组,数组中存放所有满足查找条件的信息;

//6.includes()判断字符串是否包含指定的子字符串。
let str = "Hello";
let s = str.includes("e");
console.log(s); //true
//语法:string.includes(searchvalue, start)
//searchvalue 必需值,要查找的字符串。
//start 可选值,设置从那个位置开始查找,默认为 0。

//7.repeat()字符串复制指定次数
let str = "Hello";
let s = str.repeat(2);
console.log(s); //HelloHello
//语法:string.repeat(count)
//count 必需,设置要复制的次数。

//8.replace()字符替换
let str = "Hello";
let s = str.replace("l", "o");
console.log(s); //Heolo
//语法:string.replace(searchvalue,newvalue)
//searchvalue 必须。规定子字符串或要替换的模式的 RegExp 对象。
//请注意,如果该值是一个字符串,则将它作为要检索的直接量文本模式,而不是首先被转换为RegExp对象。
//newvalue 必需。一个字符串值。规定了替换文本或生成替换文本的函数。

//9.replaceAll()字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串,该函数会替换所有匹配到的子字符串。
let str = "Hello";
let s = str.replaceAll("l", "o");
console.log(s); //Heooo
//语法同replace方法相同

//10.search()
//search() 方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串。返回与指定查找的字符串或者正则表达式相匹配的 String 对象起始位置。
let str = "Hello";
let s = str.search("lo");
console.log(s); //3
//语法:string.search(searchvalue)
//searchvalue 必须。查找的字符串或者正则表达式。

//11.slice()提取字符串的某个部分,并以新的字符串返回被提取的部分。
let str = "Hello";
let s = str.slice(1, 2);
console.log(s); //e
//语法:string.slice(start,end)
//start 必须。 要抽取的片断的起始下标,第一个字符位置为 0。如果为负数,则从尾部开始截取。
//end 可选。 紧接着要截取的片段结尾的下标。若未指定此参数,则要提取的子串包括 start 到原字符串结尾的字符串。如果该参数是负数,那么它规定的是从字符串的尾部开始算起的位置。slice(-2) 表示提取原数组中的倒数第二个元素到最后一个元素(包含最后一个元素)。

//12.split() 方法用于把一个字符串分割成字符串数组
let str = "Hello";
let s = str.split("e");
console.log(str); //Hello
console.log(s); //[ 'H', 'llo' ]
//语法:string.split(separator,limit)
//separator 可选。字符串或正则表达式,从该参数指定的地方分割 string Object。
//limit 可选。该参数可指定返回的数组的最大长度。如果设置了该参数,返回的子串不会多于这个参数指定的数组。如果没有设置该参数,整个字符串都会被分割,不考虑它的长度。

//13.substring() 方法用于提取字符串中介于两个指定下标之间的字符。
let str = "Hello";
let s = str.substring(1, 3);
console.log(str); //Hello
console.log(s); //el
//语法:string.substring(from, to)
//from 必需。一个非负的整数,规定要提取的子串的第一个字符在 string Object 中的位置。
//to 可选。一个非负的整数,比要提取的子串的最后一个字符在 string Object 中的位置多 1。
如果省略该参数,那么返回的子串会一直到字符串的结尾。

//14,15.toLowerCase()和toUpperCase()方法
let str = "Hello";
let s = str.toLowerCase();
let s2 = str.toUpperCase();
console.log(str); //Hello
console.log(s); //hello
console.log(s2);//HELLO

//16.trim()删除字符串的头尾空白符,空白符包括:空格、制表符 tab、换行符等其他空白符等
let str = "    Hello   ";
let s = str.trim();
console.log(str); //    Hello
console.log(s); //Hello

//17.includes(), startsWith(), endsWith()来确定一个字符串是否包含在另一个字符串中
let s = 'Hello world!';
console.log(s.startsWith('world', 6));// true
console.log(s.endsWith('Hello', 5));// true
console.log(s.includes('Hello', 6));// false
//注意:第二个参数,表示开始搜索的位置。

Desduplicação de string

var str="aahhgggsssjjj";
function removeRepeat(n){
var k=[];
var arr=n.split("");
for(var i=0;i<arr.length;i++){
    if(k.indexOf(arr[i])==-1){
        k.push(arr[i]);
    }
}
return k.join("");
}
removeRepeat(str);    //ahgsj

19. Por que 0,1+0,2 !== 0,3 e como torná-lo igual 

Encontrei um problema como este durante o desenvolvimento:

let n1 = 0.1, n2 = 0.2
console.log(n1 + n2)  // 0.30000000000000004

O que obtemos aqui não é o resultado desejado. Se quisermos que seja igual a 0,3, precisamos convertê-lo:

(n1 + n2).toFixed(2) // 注意,toFixed为四舍五入

toFixed(num) O método arredonda o número para um número especificado de casas decimais.

20.Como obter um valor indefinido seguro?

Como indefinido é um identificador, ele pode ser usado e atribuído como uma variável, mas isso afetará o julgamento normal de indefinido. A expressão void ___ não tem valor de retorno, portanto o resultado de retorno é indefinido. void não altera o resultado da expressão, apenas faz com que a expressão não retorne nenhum valor. Então você pode usar void 0 para ficar indefinido.

21.Qual é o resultado de typeof NaN?

NaN significa "não é um número", e NaN é um "valor de aviso" usado para apontar uma condição de erro em um tipo numérico, ou seja, "a execução de uma operação matemática não teve sucesso, e este é o resultado retornado após a falha". 

typeof NaN; // "number"

NaN é um valor especial que não é igual a si mesmo. E NaN !== NaN é verdade.

 22. Qual é a diferença entre Object.is() e os operadores de comparação "===" e "=="?

  • Ao usar o sinal de igual duplo (==) para julgamento de igualdade, se os tipos em ambos os lados forem inconsistentes, a conversão forçada de tipo será realizada antes da comparação.
  • Ao usar o sinal de igual triplo (===) para julgamento de igualdade, se os tipos em ambos os lados forem inconsistentes, a conversão forçada de tipo não será executada e falso será retornado diretamente.
  • Ao usar Object.is para julgamento de igualdade, geralmente é igual ao sinal de igual triplo. Ele lida com algumas situações especiais, como -0 e +0 não são mais iguais e dois NaN são iguais.

23.As propriedades dos objetos const podem ser modificadas?

O que const garante não é que o valor da variável não possa ser alterado, mas que o endereço de memória apontado pela variável não possa ser alterado. Para tipos básicos de dados (valores numéricos, strings, valores booleanos), o valor é armazenado no endereço de memória apontado pela variável, portanto é equivalente a uma constante.

Para dados do tipo de referência, a variável aponta para o endereço de memória dos dados e salva apenas um ponteiro. Const só pode garantir que esse ponteiro seja fixo. Quanto a saber se a estrutura de dados para a qual aponta é variável, é completamente incontrolável. 

24. O que acontecerá se new for uma função de seta?

A função arrow foi proposta no ES6. Ela não possui protótipo, nem possui este ponteiro próprio. Ela não pode usar parâmetros de argumentos, portanto não pode New uma função arrow.

As etapas de implementação do novo operador são as seguintes: 

  1. criar um objeto
  2. Atribua o escopo do construtor ao novo objeto (ou seja, aponte o atributo __proto__ do objeto para o atributo protótipo do construtor)
  3. Aponta para o código no construtor, e este no construtor aponta para o objeto (ou seja, adicionando propriedades e métodos a este objeto)
  4. Retornar novo objeto

Na segunda e terceira etapas acima, as funções de seta não podem ser executadas.

25. A diferença entre funções de seta e funções comuns

  1.  As funções de seta são mais concisas do que as funções comuns (se não houver parâmetros, basta escrever um colchete vazio diretamente, se houver apenas um parâmetro, você pode omitir os colchetes de parâmetro)

  2. As funções de seta não têm as suas próprias

  3. O ponto this herdado pela função de seta nunca mudará.

  4. Métodos como call(), apply() e bind() não podem alterar a direção disso na função de seta.

  5. Funções de seta não podem ser usadas como construtores

  6. Funções de seta não possuem argumentos próprios

  7. A função Arrow não tem protótipo

  8. As funções de seta não podem ser usadas como funções geradoras e a palavra-chave yeild não pode ser usada.

26. Princípio de implementação do novo operador

O processo de execução do novo operador:

(1) Primeiro crie um novo objeto vazio

(2) Defina o protótipo e defina o protótipo do objeto para o objeto protótipo da função.

(3) Deixe o this da função apontar para este objeto e execute o código do construtor (adicione atributos a este novo objeto)

(4) Determine o tipo de valor de retorno da função. Se for um tipo de valor, retorne o objeto criado. Se for um tipo de referência, um objeto desse tipo de referência será retornado.

Método para realizar

function objectFactory() {
  let newObject = null;
  let constructor = Array.prototype.shift.call(arguments);
  let result = null;
  if (typeof constructor !== "function") {// 判断参数是否是一个函数
    console.error("type error");
    return;
  }
  // 新建一个空对象,对象的原型为构造函数的 prototype 对象
  newObject = Object.create(constructor.prototype);
  // 将 this 指向新建对象,并执行函数
  result = constructor.apply(newObject, arguments);
  // 判断返回对象
  let flag = result && (typeof result === "object" || typeof result === "function");
  // 判断返回结果
  return flag ? result : newObject;
}
// 使用方法
objectFactory(构造函数, 初始化参数);

 27. Por que os argumentos da função são um pseudo array em vez de um array? Como iterar em um pseudo array?

argumentsÉ um objeto, suas propriedades são números aumentando sequencialmente a partir de 0, e propriedades como calleesoma e lengthassim por diante, que são semelhantes a matrizes; mas não possui propriedades de método comuns de matrizes, como forEachreduceetc., por isso são chamadas pseudo-matrizes.

Três métodos de passagem para arrays

O primeiro

function foo(){ 
  Array.prototype.forEach.call(arguments, a => console.log(a))
}
//将数组的方法应用到类数组上,这时候就可以使用call和apply方法。

O segundo tipo

function foo(){ 
  const arrArgs = Array.from(arguments) 
  arrArgs.forEach(a => console.log(a))
}
//使用Array.from方法将类数组转化成数组

O terceiro tipo

function foo(){ 
    const arrArgs = [...arguments] 
    arrArgs.forEach(a => console.log(a)) 
}
//使用展开运算符将类数组转化成数组

28. Compreendendo o AJAX e implementando uma solicitação AJAX

AJAX é a abreviatura de Asynchronous JavaScript and XML, que se refere à comunicação assíncrona por meio de JavaScript, obtendo um documento XML do servidor, extraindo dados dele e, em seguida, atualizando a parte correspondente da página web atual sem atualizar toda a página web.

Etapas para criar uma solicitação AJAX:

  1. Crie um objeto XMLHttpRequest.
  2. Use o método aberto neste objeto para criar uma solicitação HTTP . Os parâmetros exigidos pelo método aberto são o método de solicitação, o endereço da solicitação, se é assíncrono e as informações de autenticação do usuário.
  3. Antes de fazer uma solicitação, você pode adicionar algumas informações e funções de escuta a este objeto . Por exemplo, você pode adicionar informações de cabeçalho à solicitação por meio do método setRequestHeader. Você também pode adicionar uma função de escuta de status a este objeto. Um objeto XMLHttpRequest tem um total de cinco estados. Quando seu estado muda, o evento onreadystatechange será acionado. Você pode definir uma função de escuta para lidar com o resultado de uma solicitação bem-sucedida. Quando o readyState do objeto muda para 4, significa que os dados retornados pelo servidor foram recebidos. Neste momento, o status da solicitação pode ser avaliado. Se o status for 2xx ou 304, significa que o retorno é normal. Neste momento, a página pode ser atualizada por meio dos dados da resposta.
  4. Quando as propriedades do objeto e a função de monitoramento são definidas, o método enviado é finalmente chamado para iniciar uma solicitação ao servidor e os parâmetros podem ser passados ​​como o corpo dos dados enviados.
const SERVER_URL = "/server";
let xhr = new XMLHttpRequest();
// 创建 Http 请求
xhr.open("GET", url, true);
// 设置状态监听函数
xhr.onreadystatechange = function() {
  if (this.readyState !== 4) return;
  // 当请求成功时
  if (this.status === 200) {
    handle(this.response);
  } else {
    console.error(this.statusText);
  }
};
// 设置请求失败时的监听函数
xhr.onerror = function() {
  console.error(this.statusText);
};
// 设置请求头信息
xhr.responseType = "json";
xhr.setRequestHeader("Accept", "application/json");
// 发送 Http 请求
xhr.send(null);

 Use o Promise para encapsular o AJAX:

// promise 封装实现:
function getJSON(url) {
  // 创建一个 promise 对象
  let promise = new Promise(function(resolve, reject) {
    let xhr = new XMLHttpRequest();
    // 新建一个 http 请求
    xhr.open("GET", url, true);
    // 设置状态的监听函数
    xhr.onreadystatechange = function() {
      if (this.readyState !== 4) return;
      // 当请求成功或失败时,改变 promise 的状态
      if (this.status === 200) {
        resolve(this.response);
      } else {
        reject(new Error(this.statusText));
      }
    };
    // 设置错误监听函数
    xhr.onerror = function() {
      reject(new Error(this.statusText));
    };
    // 设置响应的数据类型
    xhr.responseType = "json";
    // 设置请求头信息
    xhr.setRequestHeader("Accept", "application/json");
    // 发送 http 请求
    xhr.send(null);
  });
  return promise;
}

29.Qual é a diferença entre os métodos forEach e map? 

Todos eles são usados ​​para percorrer matrizes

  • O método forEach() executará a função fornecida para cada elemento, e a operação nos dados alterará o array original.Este método não tem valor de retorno;
  • O método map() não altera o valor do array original e retorna um novo array.Os valores no novo array são os valores do array original após chamar a função;

30. Compreensão da Promessa

Promise é uma solução para programação assíncrona. É um objeto que pode obter mensagens de operações assíncronas. Sua aparência melhora muito o dilema da programação assíncrona e evita o inferno de retorno de chamada. É mais razoável do que funções e eventos de retorno de chamada de solução tradicional. E mais poderoso.

Promise, simplesmente, é um contêiner que armazena o resultado de um evento (geralmente uma operação assíncrona) que terminará no futuro. Sintaticamente, uma Promise é um objeto do qual podem ser obtidas mensagens de uma operação assíncrona. O Promise fornece uma API unificada e várias operações assíncronas podem ser processadas da mesma maneira.

As instâncias de promessa têm três estados :

  • Pendente
  • Resolvido
  • Rejeitado

Uma instância do Promise tem dois processos

  • pendente -> cumprido: resolvido
  • pendente -> rejeitado: Rejeitado (rejeitado)

Nota: Depois que o status for alterado do status contínuo para outro status, o status nunca poderá ser alterado.

31. Fale sobre a diferença entre atributos defer e async em tags de script.

As diferenças são as seguintes.

(1) O atributo defer especifica se a execução do script deve ser adiada até que a página seja carregada, e o atributo async especifica se o script será executado de forma assíncrona quando estiver disponível.

(2) adiar carrega arquivos JavaScript em paralelo e os executa na ordem das tags de script na página, enquanto async carrega arquivos JavaScript em paralelo, executa-os imediatamente após o download e não os executa na ordem das tags de script no página.

32. Fale sobre o seu entendimento sobre fechamentos.

O principal objetivo do uso de encerramentos é projetar métodos e variáveis ​​privadas. A vantagem dos encerramentos é que eles podem evitar a poluição de variáveis ​​globais; a desvantagem é que os encerramentos serão residentes na memória, aumentando o uso da memória, e o uso impróprio pode facilmente causar vazamentos de memória. Em JavaScript, funções são fechamentos, e apenas funções produzem fechamentos de escopo, que possuem três características:

(1) Função aninhada de função.

(2) Parâmetros e variáveis ​​externas podem ser referenciados dentro da função

(3) Parâmetros e variáveis ​​não serão reciclados pelo mecanismo de coleta de lixo

33. Por favor, explique o mecanismo de bolha de eventos

O borbulhamento de eventos significa que quando o evento começa, ele é aceito pelo elemento mais específico (o nó inferior do documento) e então propagado até o nó menos específico (documento). Por exemplo, se houver um elemento div em uma página e um evento de clique for adicionado, quando o evento de clique for acionado, seu processo de transferência será de div→body→html→document (sem mencionar a versão antiga), ele seguirá o DOM A árvore é passada nível por nível.

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<style type="text/css">
			.outer{
				width: 200px;
				height: 200px;
				background: red;
				z-index: 1;
			}
			.cent{
				width: 100px;
				height: 100px;
				background: blue;
				position: absolute;
				right: 0;
				left: 0;
				bottom: 0;
				top: 0;
				margin:auto;
				z-index: 2;
			}
			.insert{
				width: 50px;
				height: 50px;
				background: orange;
				position: absolute;
				right: 0;
				left: 0;
				bottom: 0;
				top: 0;
				margin:auto;
				z-index: 3;
			}
			div{
				position: relative;
			}
		</style>
	</head>
	<body>
		<div class="outer">
			<div class="cent">
				<div class="insert"></div>
			</div>
		</div>
	</body>
	<script type="text/javascript">
		var Outer=document.getElementsByClassName("outer")[0];
		var Cent=document.getElementsByClassName("cent")[0];
		var Insert=document.getElementsByClassName("insert")[0];
		var aBody=document.getElementsByTagName("body")[0];
		Outer.onclick=function(){
			console.log("aaa")
		}
		Cent.onclick=function(){
			console.log("bbb")
		}
		Insert.onclick=function(){
			console.log("ccc")
		}
		aBody.onclick=function(){
			console.log("我是body")
		}

	</script>
</html>


    Quando você clica no elemento Inserir, ccc, bbb, aaa e I am body serão exibidos em sequência. Este é o mecanismo de bolha de eventos.

34. Método para evitar bolhas de eventos 

Existem duas maneiras de evitar o borbulhamento de eventos:

  1. storpPrapagation() // não suporta versões anteriores do IE
  2. cancelarBubble=true

redação compatível

 if(event.storpPrapagação){

           event.storpPrapagação();

}outro{

           cancelarBubble=true;

}

 35.O que é delegação de eventos? Que bom é isso?

A delegação de eventos refere-se ao uso do princípio de bolha para adicionar eventos ao pai, e os benefícios de acionar efeitos de execução são os seguintes.

  • Reduza o número de eventos e melhore o desempenho.

  • Prevendo elementos futuros, elementos recém-adicionados ainda podem desencadear o evento.

  • Evite vazamentos de memória. Em versões anteriores do Positive E, evite o estouro de memória causado pela exclusão de elementos sem remover eventos.

36. Remova aleatoriamente um valor do array

var arr = ['1', '2', '3'];
var index = Math.floor((Math.random() * arr.length));
console.log(arr[index]);

37.Javascript proíbe o navegador de retornar à página anterior

<script type="text/javascript">
  $(function () {
    if (window.history && window.history.pushState) {
      $(window).on('popstate', function () {
        window.history.pushState('forward', null, '#');
        window.history.forward(1);
      });
    }
    window.history.pushState('forward', null, '#'); //在IE中必须得有这两行
    window.history.forward(1);
  })
</script>

38. Terminal móvel Jquery proíbe zoom do navegador 

Para desativar o zoom em navegadores móveis, você pode adicionar atributos à tag viewportquando a página for inicializada . Desta forma, quando o usuário tenta ampliar a página no navegador móvel, o navegador não responderá à operação de zoom do usuário.metauser-scalable=no

<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">

39. Como percorrer todas as propriedades de um objeto e exibir seus valores no console?

for (let key in obj) {
  console.log(key + ": " + obj[key]);
}

40. Como obter o tipo de dados de uma variável através de uma função?

  const getType = (value) => {
    const match = Object.prototype.toString.call(value).match(/ (\w+)]/)
    return match[1].toLocaleLowerCase()
  }
  console.log(getType());// undefined
  console.log(getType({}));// object
  console.log(getType([]));// array
  console.log(getType(1));// number
  console.log(getType('fatfish'));// string
  console.log(getType(true));// boolean
  console.log(getType(/fatfish/));// regexp

41. Gere strings aleatórias


const randomString = (len) => {
  let chars = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz123456789";
  let strLen = chars.length;
  let randomStr = "";
  for (let i = 0; i < len; i++) {
    randomStr += chars.charAt(Math.floor(Math.random() * strLen));
  }
  return randomStr;
};

randomString(10) // pfkMfjEJ6x
randomString(20) // ce6tEx1km4idRNMtym2S

42. Gere números aleatórios dentro do intervalo especificado


const randomNum = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;

randomNum(1, 10) // 6
randomNum(10, 20) // 11

43. Existem muitas maneiras de formatar dinheiro, como estas duas maneiras.

A primeira maneira de formatar dinheiro

const formatMoney = (money) => {
  return money.replace(new RegExp(`(?!^)(?=(\\d{3})+${money.includes('.') ? '\\.' : '$'})`, 'g'), ',')  
}

formatMoney('123456789') // '123,456,789'
formatMoney('123456789.123') // '123,456,789.123'
formatMoney('123') // '123'

A segunda maneira de formatar dinheiro

 Expressões regulares nos dão muita dor de cabeça, não é mesmo? Portanto, precisamos encontrar uma maneira mais fácil de formatar a moeda.

const formatMoney = (money) => {
  return money.toLocaleString()
}

formatMoney(123456789) // '123,456,789'
formatMoney(123456789.123) // '123,456,789.123'
formatMoney(123) // '123'

44.Atualizando continuamente~~~

Acho que você gosta

Origin blog.csdn.net/m0_63873004/article/details/126709330
Recomendado
Clasificación