前端基础面试题@JS篇

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介:

说说Js的数据类型都有哪些

基本类型

  • String
  • Number
  • Boolean
  • null
  • undefined
  • symbol

引用类型

  • object

说说Http状态码

1** 信息,服务器收到请求,需要请求者继续执行操作(101,升级为websocket协议)
2** 成功,操作被成功接收并处理(206,部分内容,分段传输)
3** 重定向,需要进一步操作以完成请求(301,302重定向;304命中缓存)
4** 客户端错误,请求包含语法错误或无法完成请求(401,要求身份验证;403,服务器理解客服端需求,但是禁止访问)
5** 服务器错误,服务器在处理请求的过程中发生了错误

说说ajax状态码,ajax一定是异步的吗?

ajax不一定是异步的,可以通过open方法的第三个参数来配置(默认为true,异步)

状态码:

0 - (未初始化)还没有调用send()方法
1 - (载入)已调用send()方法,正在发送请求
2 - (载入完成)send()方法执行完成
3 - (交互)正在解析响应内容
4 - (完成)响应内容解析完成,可以在客户端调用了

说说ajax是什么?优势?劣势?应该注意的问题?

ajax是一种和后台通信的标准。全称是Asynchronous Javascript And XML(异步javascript和XML)。

优势:

  • 无需刷新页面请求数据,可以使产品更快、更小、更友好
  • 可以把以前服务端的任务转嫁到客户端来处理,减轻服务器负担,节省带宽
  • 浏览器支持好,无需插件

劣势:

  • 不支持浏览器的回退按钮
  • 安全性存在问题,能够在用户不知情的情况下发送请求
  • 暴露了http交互细节
  • 对搜索引擎(网络爬虫)的支持比较弱
  • 程序不容易调试

注意的问题:

  • 浏览器兼容性问题,这个问题jQuery等库已经帮我们封装好了
  • 跨域问题,不同域之间不允许通过ajax进行访问,可以参考阮一峰老师的跨域资源共享 CORS 详解
  • 为了更快的速度和对搜索引擎友好,首页尽量不要用ajax而是服务端渲染(当然这看分场景)
  • ajax适合增删改查操作

你把下面的表达式的打印结果写出来


1.toString()  //Uncaught SyntaxError: Invalid or unexpected token
true.toString()  //"true"
[].toString()  //""
{}.toString()  //Uncaught SyntaxError: Unexpected token .
null.toString()  //Uncaught TypeError: Cannot read property 'toString' of null
undefined.toString()  //Uncaught TypeError: Cannot read property 'toString' of undefined
NaN.toString()   //"NaN"

这些需要刻意背一下,其中1和{}是语法错误。null和undefined是因为没有 toString 方法,可以使用 call 来借用(想详细了解,可以到评论区看我如何被骂的):


1..toString()   //"1"
(1).toString()  //"1"
Number(1).toString()  //"1"
({}).toString()  //[object Object]
Object.prototype.toString.call(null)   //[object Null]
Object.prototype.toString.call(undefined)   //[object Undefined]

前端性能优化你了解哪些

内容层面

  • 使用CDN
  • 单域名、多域名,单域名可以减少DNS查找次数,多域名可以增加浏览器并行下载数量,这需要权衡,一般同一个域下不要超过四个资源。
  • 避免重定向(分场景)
  • 避免404

网络层面

  • 利用缓存,可以参考另一篇文章手写文件服务器,说说前后端交互
  • 文件压缩(通过响应头Accept-Encoding: gzip, deflate, br告诉服务器你支持的压缩类型)
  • 按需加载,提取公共代码,tree-shaking等(都可以通过webpack来实现)
  • 减少cookie大小
  • 文件合并,通过css雪碧图合并图片
  • 文件预加载、图片懒加载

渲染层间

  • js放底部,css放顶部
  • 减少reflow(回流)和repaint(重绘)
  • 减少dom节点

代码层面

  • 缓存dom节点,减少节点查找,css选择器层级优化
  • 减少dom节点操作
  • 合理使用break、continue、return等,优化循环
  • 像react用到的事件委托、对象池等手段

说说浏览器的reflow和repaint

浏览器解析过程

  1. 解析html生成dom树
  2. 解析css
  3. 把css应用于dom树,生成render树(这里记录这每一个节点和它的样式和所在的位置)
  4. 把render树渲染到页面

reflow(回流)

reflow翻译为回流,指的是页面再次构建render树。每个页面至少发生一次回流,就是第一次加载页面的时候

此外,当页面中有任何改变可能造成文档结构发生改变(即元素间的相对或绝对位置改变),都会发生reflow,常见的有:

  • 添加或删除元素(opacity:0除外,它不是删除)
  • 改变某个元素的尺寸或位置
  • 浏览器窗口改变(resize事件触发)

repaint(重绘)

repaint翻译为重绘,它可以类比为上面的第四步,根据render树绘制页面,它的性能损耗比回流要小。每次回流一定会发生重绘。此外,以下操作(不影响文档结构的操作,影响结构的会发生回流)也会发生重绘:

  1. 元素的颜色、透明度改变
  2. text-align等

浏览器优化

我们不太容易精确知道哪些操作具体会造成哪些元素回流,不同的浏览器都有不同的实现。但是确定是他们的的耗时是比较长的,因为涉及到大量的计算。

浏览器为了提升性能也对这个问题进行了优化。方案就是维护一个队列,把所有需要回流和重绘的操作都缓存起来,一段时间之后再统一执行。但是,有的时候我们需要获取一些位置属性,当我们一旦调用这些api的时候,浏览器不得不立即计算队列以保证提供的数据是准确的。例如以下操作:

  • offsetTop, offsetLeft, offsetWidth, offsetHeight
  • scrollTop/Left/Width/Height
  • clientTop/Left/Width/Height
  • width,height
  • getComputedStyle或者IE的currentStyle

注意问题

  1. 批量处理
  • 使用DocumentFragment进行缓存,这样只引发一次回流
  • 把频繁操作的元素先display:null,只引发两次回流
  • cloneNode和replaceChild,只引发两次回流
  1. 不要频繁更改style,而是更改class
  2. 避免频繁调用offsetTop等属性,在循环前把它缓存起来
  3. 绝对定位具有复杂动画的元素,否则会引起父元素和后续大量元素的频繁回流

如何去除字符串首位空格?



//es6
' ab '.trim()      //"ab" 
//正则
' ab '.replace(/^\s*|\s*$/g,'')  //"ab"

如何获取url中的查询字符串



function queryUrlParameter(str) {
    let obj = {}
    let reg = /([^?=&#]+)=([^?=&#]+)/g;
    str.replace(reg, function () {
        obj[arguments[1]] = arguments[2]
    })
    //如果加上hash
    // reg = /#([^?&=#]+)/g
    // if (reg.test(str)) {
    //     str.replace(reg, function () {
    //         obj.hash = arguments[1]
    //     })
    // }
    return obj
}
console.log(queryUrlParameter('http://www.baidu.com?a=1&b=2#12222'))  //{ a: '1', b: '2'}

如何实现一个深拷贝、深比较

深拷贝


function clone(obj) {
  if (obj == null || typeof obj !== 'object') return obj

  let newObj = null

  // 时间对象有特殊性
  if (obj.constructor === Date) {
    newObj = new obj.constructor(obj)
  } else {
    newObj = obj.constructor()
  }


  for (let key in Object.getOwnPropertyDescriptors(obj)) {
    newObj[key] = clone(obj[key])
  }
  return newObj
}

深比较


function deepCompare(a, b){
  if(a === null
    || typeof a !== 'object'
    || b === null
    || typeof b !== 'object'){
    return a === b
  }

  const propsA = Object.getOwnPropertyDescriptors(a)
  const propsB = Object.getOwnPropertyDescriptors(b)
  if(Object.keys(propsA).length !== Object.keys(propsB).length){
    return false
  }

  return Object.keys(propsA).every( key => deepCompare(a[key], b[key]))

}

如何实现函数节流和防抖

节流


function throttle(fn, delay) {
  delay = delay || 50
  let statTime = 0
  return function () {
    statTime === 0 && fn.apply(arguments)
    let currentTime = new Date()
    if (currentTime = statTime > delay) {
      fn.apply(arguments)
      statTime = currentTime
    }
  }
}

let throttleFn = throttle(fn)
throttleFn()
throttleFn()
throttleFn()
throttleFn()//只会执行一次

防抖



function debounce(fn, delay) {
  delay = delay || 50
  let timer = null
  return function () {
    let self = this
    clearTimeout(timer)
    timer = setTimeout(fn.bind(self, arguments), delay);
  }
}

你给我写一个原生bind方法



Function.prototype._bind = function (context) {
  let self = this
  let args_1 = [].prototype.slice.call(arguments, 1)
  return function () {
    let args_2 = [].prototype.slice.call(arguments)
    let args = args_1.concat(args_2)
    return self.apply(context, args)
  }
}

这只是对bind的一种简单实现,如果有兴趣了解更多可以参考Javascript中bind()方法的使用与实现

如何实现一个数组的展平



function (ary) {
    return ary.toString().split(',')
}

这是一个投机取巧的方法(面试写个这个也凑合吧),如果有兴趣可以搜索一下其他实现方法

如何添加、删除、移动、复制DOM节点

创建

  • createTextNode() //创建文本节点
  • createElement() //创建元素节点
  • createDocumentFragment() //创建文档碎片

操作

  • appendChild() //增加
  • removeChild() //删除
  • replaceChild() //替换
  • insertBefore() //插入

查找

  • getElementById()
  • getElementByTagName()
  • getElementByName()

原文发布时间为:2018年05月18日
原文作者:寒东设计师
本文来源:  掘金  如需转载请联系原作者





相关文章
|
2月前
|
JavaScript 前端开发 程序员
前端原生Js批量修改页面元素属性的2个方法
原生 Js 的 getElementsByClassName 和 querySelectorAll 都能获取批量的页面元素,但是它们之间有些细微的差别,稍不注意,就很容易弄错!
|
2月前
|
JavaScript 前端开发 Java
springboot解决js前端跨域问题,javascript跨域问题解决
本文介绍了如何在Spring Boot项目中编写Filter过滤器以处理跨域问题,并通过一个示例展示了使用JavaScript进行跨域请求的方法。首先,在Spring Boot应用中添加一个实现了`Filter`接口的类,设置响应头允许所有来源的跨域请求。接着,通过一个简单的HTML页面和jQuery发送AJAX请求到指定URL,验证跨域请求是否成功。文中还提供了请求成功的响应数据样例及请求效果截图。
springboot解决js前端跨域问题,javascript跨域问题解决
|
2月前
|
JSON JavaScript 前端开发
[JS]面试官:你的简历上写着熟悉jsonp,那你说说它的底层逻辑是怎样的?
本文介绍了JSONP的工作原理及其在解决跨域请求中的应用。首先解释了同源策略的概念,然后通过多个示例详细阐述了JSONP如何通过动态解释服务端返回的JavaScript脚本来实现跨域数据交互。文章还探讨了使用jQuery的`$.ajax`方法封装JSONP请求的方式,并提供了具体的代码示例。最后,通过一个更复杂的示例展示了如何处理JSON格式的响应数据。
42 2
[JS]面试官:你的简历上写着熟悉jsonp,那你说说它的底层逻辑是怎样的?
|
2月前
|
缓存 JavaScript 前端开发
JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用
本文深入讲解了 JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用。
58 5
|
2月前
|
缓存 前端开发 JavaScript
JavaScript前端路由的实现原理及其在单页应用中的重要性,涵盖前端路由概念、基本原理、常见实现方式
本文深入解析了JavaScript前端路由的实现原理及其在单页应用中的重要性,涵盖前端路由概念、基本原理、常见实现方式(Hash路由和History路由)、优点及挑战,并通过实际案例分析,帮助开发者更好地理解和应用这一关键技术,提升用户体验。
84 1
|
2月前
|
JSON 前端开发 JavaScript
聊聊 Go 语言中的 JSON 序列化与 js 前端交互类型失真问题
在Web开发中,后端与前端的数据交换常使用JSON格式,但JavaScript的数字类型仅能安全处理-2^53到2^53间的整数,超出此范围会导致精度丢失。本文通过Go语言的`encoding/json`包,介绍如何通过将大整数以字符串形式序列化和反序列化,有效解决这一问题,确保前后端数据交换的准确性。
57 4
|
2月前
|
机器学习/深度学习 自然语言处理 前端开发
前端神经网络入门:Brain.js - 详细介绍和对比不同的实现 - CNN、RNN、DNN、FFNN -无需准备环境打开浏览器即可测试运行-支持WebGPU加速
本文介绍了如何使用 JavaScript 神经网络库 **Brain.js** 实现不同类型的神经网络,包括前馈神经网络(FFNN)、深度神经网络(DNN)和循环神经网络(RNN)。通过简单的示例和代码,帮助前端开发者快速入门并理解神经网络的基本概念。文章还对比了各类神经网络的特点和适用场景,并简要介绍了卷积神经网络(CNN)的替代方案。
187 1
|
2月前
|
JavaScript 前端开发 开发者
前端框架对比:Vue.js与Angular的优劣分析与选择建议
【10月更文挑战第27天】在前端开发领域,Vue.js和Angular是两个备受瞩目的框架。本文对比了两者的优劣,Vue.js以轻量级和易上手著称,适合快速开发小型到中型项目;Angular则由Google支持,功能全面,适合大型企业级应用。选择时需考虑项目需求、团队熟悉度和长期维护等因素。
64 1
|
3月前
|
存储 人工智能 前端开发
前端大模型应用笔记(三):Vue3+Antdv+transformers+本地模型实现浏览器端侧增强搜索
本文介绍了一个纯前端实现的增强列表搜索应用,通过使用Transformer模型,实现了更智能的搜索功能,如使用“番茄”可以搜索到“西红柿”。项目基于Vue3和Ant Design Vue,使用了Xenova的bge-base-zh-v1.5模型。文章详细介绍了从环境搭建、数据准备到具体实现的全过程,并展示了实际效果和待改进点。
223 14
|
3月前
|
JavaScript 前端开发 程序员
前端学习笔记——node.js
前端学习笔记——node.js
60 0

热门文章

最新文章