前端面试题-基础篇(一)

最近在准备面试,搜集了一些偏基础的面试题,简单记录一下。

1、列举一些常用的ES6新特性

1、const、let (块级作用域 {})
  • 不存在变量提升,不能在变量声明之前使用,且只在当前作用域有效,避免了全局命名冲突
  • let用来声明变量,const用来声明常量,const声明的值不能被修改(对于引用类型,指的是引用的地址不能修改)

2、箭头函数 ()=>{}

  • 语法简洁,自动绑定上下文,解决了回调函数中this指向问题;函数体内的this 指向定义时所在的对象的this
  • 不可以当做构造函数(不能new)
  • 不可以使用arguments(es5)对象,可以用rest(es6)

3、结构赋值 const {a,b} = {a:1,b:2}

  • 按照一定格式从数组或对象中提取值,然后对变量赋值
  • 简化代码

4、函数默认参数 funtion fn(a=1){}

  • 允许在函数定义时为参数提供默认值,在调用时未传递参数,将使用默认值

5、扩展运算符 ...

  • 可将数组或对象展开成独立的元素,或配合{}/[]将多个元素合并成对象/数组

6、模板字符串 ``

  • 使用``拼接字符串可在其通过${}插入变量和表达式,能极大提高代码的可读性和维护性

7、Promise对象 new Promise((resolve,reject)=>{})

  • 异步编程的一种解决方案,存在三种状态:padding(进行中), fulfilled(成功),rejected(失败)
  • Promise.all[p1,p2] 全部resolve才会返回resolve,只要其中一个reject则返回reject
  • Promise.race[p1,p2] 取最快处理完成的p作为整个的返回结果

8、类和模块

  • 引入了class语法糖,便于面向对象编程。类可通过extends关键字实现继承,使用super调用父类的方法
  • 引入模块化的概念,通过import和export关键字可以方便的导入&导出模块
  • es6module、CommondJS、AMD:前者是编译时加载,后两者是运行时加载
  •  

2、JS事件循环机制

JS简介:JS是单线程语言,目的是为了在操作DOM的时候避免冲突;但是遇到耗时脚本,页面会产生堵塞,因此加入异步模式。

异步任务:不进入主线程,直接进入任务队列的任务,异步任务执行完成后会通知主线程去执行其回调函数。
     异步任务包括宏任务(script,setTimeout,setInterval,I/O,postMessage...)和微任务(Promise,MutaionObserver...)

事件循环机制:当JS代码执行时,所有任务(同步/异步)都在主线程上执行,形成一个执行栈;执行栈之外还有任务队列(宏队列和微队列),用于存放等待执行的异步回调;
        执行过程若遇到宏任务则会将其回调函数加到宏队列,遇到微任务则将其回调函数加到微队列,直到本次宏任务(通常是从script开始)执行结束后,就会执行微队列中的任务;
        当微队列中的任务全部执行结束,就会检查宏任务队列中有无可执行的任务,有则执行该宏任务,之后再检查微队列并执行,依次循环,直至无宏任务可执行,则结束
循环机制的核心是 让JS既做到单线程,又不会阻塞脚本执行

3、谈谈你对闭包的理解

概念:闭包是一个函数以及其绑定的周边环境状态的引用的组合,简单来讲就是内部函数可以访问到外部函数的作用域(私有变量)
eg:

注:以上两种方式在执行时都会产生闭包,并不一定需要返回函数,只要内部函数在执行时引用了外部函数的变量即可。

常使用的场景:1、防抖节流函数、函数柯里化、链式调用

小结:闭包可以保护变量,避免被垃圾回收机制清除。这是优点也是缺点,变量都存在内存中,过渡使用可能造成内存泄漏。

4、如何准确判断变量的数据类型

typeof:无法判断除Function外的引用类型
instanceof:无法判断基本类型
constructor:判断null和undefined会报错(无constructor)
Object.prototype.toString.call() 可以准确判断所有变量的数据类型

原理:先来看一下toString方法,在JavaScript中,所有类都继承于Object,因此toString()方法应该也被继承了,但由下图可见事实并不像我们想的那样,
其实各数据类型使用toString()后的结果表现不一的原因在于:所有类在继承Object的时候,改写了toString()方法。 
Object原型上的方法是可以输出数据类型的。因此我们想判断数据类型时,也只能使用原始方法。
继而有了此方法:Object.prototype.toString.call(obj)


  

 5、页面上有一万个button,你会如何绑定这些按钮的click事件

在其共同的父元素身上绑定click事件,通过事件对象判断点击的是哪个button

6、js深浅拷贝

浅拷贝:拷贝基本数据类型时,直接赋值即可,使用无影响;当拷贝引用类型时,拷贝的只是数据的指针,拷贝后的变量如有修改,会影响源数据
深拷贝:在内存的堆区域中重新分配内存,拥有不同的地址(引用),能避开浅拷贝的缺点
如何实现深拷贝(常用):
1、lodash工具库 cloneDeep
2、JSON.parse(JSON.stringify()) 缺点:无法拷贝内部函数
3、手写cloneDeep
function cloneDeep(source){
  let obj = {}
  if(source instanceof Array){
    obj = []
  }
  for(let key in source){
    let value = source[key]
    obj[key] = (typeof value === "object" && value !==null) ? cloneDeep(value) : value
  }
  return obj
}

7、js捕获页面异常

1、try-catch-finally 适用于捕获局部代码块的异常
try {
    console.log(a); // 这里没有定义变量a,会抛出一个ReferenceError的异常
} catch (e) {
    console.error(e.message); // 输出异常信息
} finally {
    console.log("finally"); // 最终会输出“finally”
}

2、
window.onerror 常用于捕获页面全局异常
window.onerror = function(message, source, lineno, colno, error) {
  // message表示异常信息,source表示引起异常的文件名(可能为空),lineno和colno表示异常所在代码的行数和列数(可能为空),error表示异常的对象(可能为空) }

8、cookie、localstorage、sessionStorage的作用和区别

cookie:服务器发给客户端的信息,常用于在客户端发起请求时服务器校验用户身份,最大4kb,默认有效期为浏览器窗口的会话期,同源窗口共享
localstorage:存储大小5MB,有效期永久,除非手动清除,不参与服务器通信;常用于数据缓存
sessionStorage:存储大小5MB,仅在浏览器窗口会话期有效,不同窗口不共享

9、什么是跨域,常用的跨越解决方式有哪些 

跨域:浏览器的同源策略造成的,对js的安全限制。协议、域名、端口有其中一个不同则视为跨域
常见的解决方式:
  JSONP:利用script标签没有跨域限制,通过script.src发送http请求,http链接带上callback参数,服务端将返回数据拼接在callback中(缺点:只能发送GET请求,且需服务端配合)

            

   CORS(跨域资源共享):客户端发起请求时带上请求头(Origin,Access-Control-Request-Method(复杂请求预检用)) 

              服务器配置响应头 Access-Control-Allow-Origin(*或者具体的地址)

                      Access-Control-Allow-Methods
                      Access-Control-Allow-Headers

   nginx反向代理:利用nginx配置一个代理服务器,代理服务器域名和页面域名相同,使用代理服务器去访问其他域名接口

   postMessage:HTML5新增的api,可实现跨域通信

10、http常见状态码

2xx:请求成功
3xx:重定向
4xx:客户端请求错误
5xx:服务器响应错误

未完待续~

posted @ 2024-06-18 15:43  527xyz  阅读(18)  评论(0编辑  收藏  举报