2021年这些js相关的前端面试题真的值得收藏(二)

简介: 2021年这些js相关的前端面试题真的值得收藏

8.Promise的理解,和promise都有哪些方法


Promise,就是一个对象,用来传递异步操作的消息,避免了层层嵌套的回调函数。它代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个事件提供统一的API,可供进一步处理。 
(1)对象的状态不受外界影响。有三种状态:Pending(进行中)、Resolved(已完成,又称Fulfilled)和Rejected(已失败)。 
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从Pending变为Resolved和从Pending变为Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果


9.原型和原型链的理解


我们创造的每一个函数都有一个prototype(原型)属性。这个属性是一个指针,指向原型对 象。在默认情况下,所有的原型对象都会有一个constructor(构造函数)属性,这个属性包含一个指向prototype属相所在的指针。当调用构造函数创建一个新实例之后,该实例内部将包含一个指针(内部属性),指向构造函数的原型对象。
<u>https://juejin.im/post/5ae95290518825672c00c0a4</u>

10:异步方式

1. Promise
2. Generator 
3. Async-await
4. Node.js 中的nextTick()和setimmediate()
5. async库

11:修复bug或添加新功能的常见工作流(git命令)是什么?空和未定义的javascript有什么区别?

git flow feature start f1 添加新特性,这个操作创建了一个基于develop的特性分支,并切换到这个分支之下。
git flow feature finish f1 完成新特性,这个操作会合并f1分支到develop分支,并删除特性分支,切换回develop分支。
git flow feature publish f1 发布新分支,发布新特性分支到远程服务器,其它用户也可以使用这分支。
修复bug:
git flow hotfix start VERSION [BASENAME] 创建hotfix分支,VERSION 参数标记着修正版本,[BASENAME]为finish release时填写的版本号。

12:您使用什么框架来编写单元测试,写下一个案例来验证调用的函数

一、问题描述: 
在一个升序数组中,使用折半查找得到要查询的值的索引位置。如:

var a=[1,2,3,4,5,6,7,8,9];
search(a,3);//返回2
search(a,1);//左边界,返回0
search(a,9);//右边界,返回8
search(a,0);//比最小的值还小,返回"您查找的数值不存在"
search(a,10);//比最大的值还大,返回"您查找的数值不存在"

注:折半查找必须在有序数组中才有效,无序的数组不能实现查找功能。比如:在[10,5,6,7,8,9,20]中查找10,中间索引位置的值为7,比较得出7比10小,因而应该在右子数组中查找,实际上不可能找到10;

二、我的实现

  function search(arr,num) {
            var l=arr.length;
            var left=0;
            var right=l-1;
            var center=Math.floor((left+right)/2);
            while(left<=l-1&&right>=0){
                if (arr[center]==num) return center;
                if (left==right) return "您查找的数不存在";
                if (arr[center]>num) {
                    right=center-1;
                    center=Math.floor((left+right)/2);
                }else if (arr[center]<num) {
                    left=center+1;
                    center=Math.floor((left+right)/2);
                }
            }
        }
        var a=[1,2,3,4,5,6,7,8,9];
        console.log(search(a,-2));
说明: 
1、基本思路: 
每次比较,如果数组中间索引位置的值比要查找的值大,就转而在数组中间位置之前的子数组中查找;相反,如果数组中间索引位置的值比要查找的值大,就转而在数组中间位置之后的子数组中查找;如果数组中间索引位置的值恰好等于要查找的值,就返回该索引位置。
2、left定义查找范围的起始位置,right定义查找范围的结束位置,center定义查找范围的中间位置。
3、while中的逻辑说明: 
(1)由于不知道具体查找查找多少次,while是比较好的选择; 
(2)循环结束条件: 
a、一旦当right小于0时,就不再查找,再纠缠也不会有结果。例如:在a=[1,2,3,4,5,6,7,8,9]中查找0,当查找范围变为left=0,right=0,center=0时,进入while语句,由于arr[center]>0,故执行 
right=center-1;center=Math.floor((left+right)/2); 
得到right=-1此时应不再进入循环; 
b、一旦当left>l-1时,就不再查找,同样再纠缠也不会有结果。例如:在a=[1,2,3,4,5,6,7,8,9]中查找10,当查找范围变为left=8,right=8,center=8时,进入while语句,由于arr[center]<10,故执行 
left=center;center=Math.floor((left+right)/2); 
得到left=9,此时应不再进入循环;
4、始终是通过center匹配到要查找的值;
5、Math.floor处理了查找范围长度为偶数的情况;
6、当left==right了,而arr[center]==num却没执行,可以得出结论查找不到的;
7、当arr[center]==num时,整个函数都结束了,后面语句是不会执行的。

13.编写一个regex表达式以查找内容,内容以2个数字开头,以结尾

var reg = /1[0-9]$/

14.push 添加数组后, 是怎么响应的

push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度


注释:该方法会改变数组的长度。


语法:


arrayObject.push(newelement1,newelement2,…,newelementX)


参数描述


newelement1 必需。要添加到数组的第一个元素。


newelement2 可选。要添加到数组的第二个元素。


newelementX 可选。可添加多个元素。


push() 方法可把它的参数顺序添加到 arrayObject 的尾部。它直接修改 arrayObject,而不是创建一个新的数组。push() 方法和 pop() 方法使用数组提供的先进后出栈的功能。

15.js基本数据类型

Undefined、Null、Bollean、Number、String

16.js中=的区别是什么

前者会自动转换类型

后者不会

17.for和for in 区别

语法结构上不同,

for 一般用来遍历数组的,是比较简单的操作


for in 一般用来遍历对象,虽然for in 也能遍历数组,但是会存在


以下几个问题:


1、index索引为字符串型数字,不能直接进行几何运算


2、遍历顺序有可能不是按照实际数组的内部顺序


3、使用for in会遍历数组所有的可枚举属性,包括原型。例如上栗


的原型方法method和name属性


这也是为什么用for不用for in的区别,如果是遍历普通数组的话,

用for是最好的选择,但是如果是对象,用for in就好了。

18.js中=的区别是什么

操作数1 == 操作数2,  操作数1 === 操作数2
双等号==:   
(1)如果两个值类型相同,再进行三个等号(===)的比较  
(2)如果两个值类型不同,也有可能相等,需根据以下规则进行类型转换在比较:   
1)如果一个是null,一个是undefined,那么相等    
2)如果一个是字符串,一个是数值,把字符串转换成数值之后再进行比较
三等号===:  
(1)如果类型不同,就一定不相等  
(2)如果两个都是数值,并且是同一个值,那么相等;如果其中至少一个是NaN,那么不相      等。(判断一个值是否是NaN,只能使用isNaN( ) 来判断)  
(3)如果两个都是字符串,每个位置的字符都一样,那么相等,否则不相等。  
(4)如果两个值都是true,或是false,那么相等  
(5)如果两个值都引用同一个对象或是函数,那么相等,否则不相等  
(6)如果两个值都是null,或是undefined,那么相等

19:for和for in 区别

for in:
1.for...in 语句用于对数组或者对象的属性进行循环操作。
2.for ... in 循环中的代码每执行一次,就会对数组的元素或者对象的属性进行一次操作。
3.for...in语句以任意顺序遍历一个对象的可枚举属性。对于每个不同的属性,语句都会被执行。
for :
1.for循环是对数组的元素进行循环,而不能引用于非数组对象。

20:数组去重的方法

第一种:
function uniq(array){
   var temp = []; //一个新的临时数组
   for(var i = 0; i < array.length; i++){
       if(temp.indexOf(array[i]) == -1){
           temp.push(array[i]);
       }
   }
   return temp;
}
var aa = [1,2,2,4,9,6,7,5,2,3,5,6,5];
console.log(uniq(aa));
第二种:对象键值法去重
function uniq(array){
    var temp = {}, r = [], len = array.length, val, type;
    for (var i = 0; i < len; i++) {
        val = array[i];
        type = typeof val;
        if (!temp[val]) {
            temp[val] = [type];
            r.push(val);
        } else if (temp[val].indexOf(type) < 0) {
            temp[val].push(type);
            r.push(val);
        }
    }
    return r;
}
var aa = [1,2,"2",4,9,"a","a",2,3,5,6,5];
console.log(uniq(aa));
第三种:排序后相邻去除法
function uniq(array){
    array.sort();
    var temp=[array[0]];
    for(var i = 1; i < array.length; i++){
        if( array[i] !== temp[temp.length-1]){
            temp.push(array[i]);
        }
    }
    return temp;
}
var aa = [1,2,"2",4,9,"a","a",2,3,5,6,5];
console.log(uniq(aa));
第四种:数组下标法
function uniq(array){
    var temp = [];
    for(var i = 0; i < array.length; i++) {
        //如果当前数组的第i项在当前数组中第一次出现的位置是i,才存入数组;否则代表是重复的
        if(array.indexOf(array[i]) == i){
            temp.push(array[i])
        }
    }
    return temp;
}
var aa = [1,2,"2",4,9,"a","a",2,3,5,6,5];
console.log(uniq(aa));
第五种:优化遍历数组法
function uniq(array){
    var temp = [];
    var index = [];
    var l = array.length;
    for(var i = 0; i < l; i++) {
        for(var j = i + 1; j < l; j++){
            if (array[i] === array[j]){
                i++;
                j = i;
            }
        }
        temp.push(array[i]);
        index.push(i);
    }
    console.log(index);
    return temp;
}
var aa = [1,2,2,3,5,3,6,5];
console.log(uniq(aa));

21:排序的方法

第一种:冒泡排序:
var arr = [1,4,-8,-3,6,12,9,8];
function bubbleSort(arr){
        for (var i = 0; i < arr.length; i++) {
            for (var j = 0; j < arr.length-i-1; j++) {
                if(arr[j] > arr[j+1]){
                    var c = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = c;
                }
            }
        }
        return arr;
    }    
    console.log(bubbleSort(arr));
快速排序:
var arr = [1,4,-8,-3,6,12,9,8];
function quicksort(arr){
   if(arr.length <= 1){       
       return arr;       
       }       
       var middleIndex = Math.floor(arr.length/2);       
       var middleNum = arr.splice(middleIndex,1);       
       var left = [], right = [];       
       for (var i = 0; i < arr.length; i++) {           
               if(arr[i] < middleNum){               
                  left.push(arr[i]);           
                  } else {               
                    right.push(arr[i]);           
                     }       
               }        
               return quicksort(left).concat(middleNum, quicksort(right));   
  }   
    console.log(quicksort(arr));
选择排序:
var arr = [1,4,-8,-3,6,12,9,8];
function selectSort(arr){       
    for(var i=0;i<arr.length;i++){           
    //设置当前范围最小值和索引           
    var min = arr[i];           
    var minIndex = i;          
    //在该范围选出最小值          
    for(var j=i+1;j<arr.length;j++){             
         if(min>arr[j]){                   
               min = arr[j];                   
               minIndex = j;               
         }           
    }           
    //将最小值插入,并将原来位置的最小值删除            
    arr.splice(i,0,min);           
    arr.splice(minIndex+1,1);       
    }       
    return arr;   
    }        
    console.log(selectSort(arr));
插入排序:
var array = [1,4,-8,-3,6,12,9,8]; 
function selectSort(arr){
    for(var i=0;i<arr.length;i++){
    //设置当前范围最小值和索引 
            var min = arr[i];
            var minIndex = i; 
            //在该范围选出最小值 
            for(var j=i+1;j<arr.length;j++){
                if(min>arr[j]){
                     min = arr[j];
                     minIndex = j; 
                }
            }
            //将最小值插入,并将原来位置的最小值删除 
            arr.splice(i,0,min); 
            arr.splice(minIndex+1,1);
       }
  }
            selectSort(array);
            document.write(array);
相关文章
|
25天前
|
JavaScript 前端开发 程序员
前端原生Js批量修改页面元素属性的2个方法
原生 Js 的 getElementsByClassName 和 querySelectorAll 都能获取批量的页面元素,但是它们之间有些细微的差别,稍不注意,就很容易弄错!
|
22天前
|
JavaScript 前端开发 Java
springboot解决js前端跨域问题,javascript跨域问题解决
本文介绍了如何在Spring Boot项目中编写Filter过滤器以处理跨域问题,并通过一个示例展示了使用JavaScript进行跨域请求的方法。首先,在Spring Boot应用中添加一个实现了`Filter`接口的类,设置响应头允许所有来源的跨域请求。接着,通过一个简单的HTML页面和jQuery发送AJAX请求到指定URL,验证跨域请求是否成功。文中还提供了请求成功的响应数据样例及请求效果截图。
springboot解决js前端跨域问题,javascript跨域问题解决
|
25天前
|
缓存 JavaScript 前端开发
JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用
本文深入讲解了 JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用。
38 5
|
23天前
|
缓存 前端开发 JavaScript
JavaScript前端路由的实现原理及其在单页应用中的重要性,涵盖前端路由概念、基本原理、常见实现方式
本文深入解析了JavaScript前端路由的实现原理及其在单页应用中的重要性,涵盖前端路由概念、基本原理、常见实现方式(Hash路由和History路由)、优点及挑战,并通过实际案例分析,帮助开发者更好地理解和应用这一关键技术,提升用户体验。
57 1
|
27天前
|
JSON 前端开发 JavaScript
聊聊 Go 语言中的 JSON 序列化与 js 前端交互类型失真问题
在Web开发中,后端与前端的数据交换常使用JSON格式,但JavaScript的数字类型仅能安全处理-2^53到2^53间的整数,超出此范围会导致精度丢失。本文通过Go语言的`encoding/json`包,介绍如何通过将大整数以字符串形式序列化和反序列化,有效解决这一问题,确保前后端数据交换的准确性。
33 4
|
4月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
28天前
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
|
1月前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
1月前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
53 4
|
2月前
|
算法 Java 数据中心
探讨面试常见问题雪花算法、时钟回拨问题,java中优雅的实现方式
【10月更文挑战第2天】在大数据量系统中,分布式ID生成是一个关键问题。为了保证在分布式环境下生成的ID唯一、有序且高效,业界提出了多种解决方案,其中雪花算法(Snowflake Algorithm)是一种广泛应用的分布式ID生成算法。本文将详细介绍雪花算法的原理、实现及其处理时钟回拨问题的方法,并提供Java代码示例。
89 2