JS面试题

变量类型和计算

JS中typeof的类型有哪些

console.log( typeof undefined); //undefined
console.log( typeof 123); //number
console.log( typeof '123'); //string
console.log( typeof true); //boolean
console.log( typeof [ 1, 2, 3]); //object
console.log( typeof { "id": 11}); //object
console.log( typeof null); //object 
console.log( typeof console.log); //function

说说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等

注意问题

  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 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);
  }
}

如何实现一个数组的展平

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

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

创建

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

操作

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

查找

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


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值