2019前端面试系列——JS面试题

简介: 2019前端面试系列——JS面试题目录判断 js 类型的方式浅拷贝和深拷贝数组去重的方法DOM 事件有哪些阶段?谈谈对事件代理的理解介绍下 promise.allasync 和 awaitES6 的 class 和构造函数的区别transform、translate、transition 分别是...

2019前端面试系列——JS面试题
目录

判断 js 类型的方式
浅拷贝和深拷贝
数组去重的方法
DOM 事件有哪些阶段?谈谈对事件代理的理解
介绍下 promise.all
async 和 await
ES6 的 class 和构造函数的区别
transform、translate、transition 分别是什么属性?CSS 中常用的实现动画方式
介绍一下rAF(requestAnimationFrame)
javascript 的垃圾回收机制讲一下
对前端性能优化有什么了解?一般都通过那几个方面去优化的?

回到顶部
判断 js 类型的方式

  1. typeof
    可以判断出'string','number','boolean','undefined','symbol'

但判断 typeof(null) 时值为 'object'; 判断数组和对象时值均为 'object'
原文地址https://www.cnblogs.com/chenwenhao/p/11253403.html

  1. instanceof
    原理是 构造函数的 prototype 属性是否出现在对象的原型链中的任何位置

function A() {}
let a = new A();
a instanceof A //true,因为 Object.getPrototypeOf(a) === A.prototype;

  1. Object.prototype.toString.call()
    常用于判断浏览器内置对象,对于所有基本的数据类型都能进行判断,即使是 null 和 undefined
  2. Array.isArray()
    用于判断是否为数组

回到顶部
浅拷贝和深拷贝
浅拷贝
Object.assign()
Array.prototype.slice()
扩展运算符 ...
深拷贝
JSON.parse(JSON.stringify())
递归函数
function cloneObject (obj) {

 var newObj = {}  //如果不是引用类型,直接返回
  if (typeof (obj) !== 'object') {
      return obj
 }
 //如果是引用类型,遍历属性
else{
    for (var attr in obj) {
    //如果某个属性还是引用类型,递归调用
    newObj[attr] = cloneObject(obj[attr])
            }
   }
return newObj

}
如何实现一个深拷贝
详细解析赋值、浅拷贝和深拷贝的区别

回到顶部
数组去重的方法
1.ES6 的 Set
let arr = [1,1,2,3,4,5,5,6]
let arr2 = [...new Set(arr)]
2.reduce()
let arr = [1,1,2,3,4,5,5,6]
let arr2 = arr.reduce(function(ar,cur) {
if(!ar.includes(cur)) {

ar.push(cur)

}

return ar
},[])
3.filter()
// 这种方法会有一个问题:[1,'1']会被当做相同元素,最终输入[1]
let arr = [1,1,2,3,4,5,5,6]
let arr2 = arr.filter(function(item,index) {
// indexOf() 方法可返回某个指定的 字符串值 在字符串中首次出现的位置
return arr.indexOf(item) === index
})
回到顶部
DOM 事件有哪些阶段?谈谈对事件代理的理解
分为三大阶段:捕获阶段--目标阶段--冒泡阶段

事件代理简单说就是:事件不直接绑定到某元素上,而是绑定到该元素的父元素上,进行触发事件操作时(例如'click'),再通过条件判断,执行事件触发后的语句(例如'alert(e.target.innerHTML)')

好处:(1)使代码更简洁;(2)节省内存开销

回到顶部
介绍下 promise.all

  Promise.all()方法将多个Promise实例包装成一个Promise对象(p),接受一个数组(p1,p2,p3)作为参数,数组中不一定需要都是Promise对象,但是一定具有Iterator接口,如果不是的话,就会调用Promise.resolve将其转化为Promise对象之后再进行处理。
  使用Promise.all()生成的Promise对象(p)的状态是由数组中的Promise对象(p1,p2,p3)决定的。

如果所有的Promise对象(p1,p2,p3)都变成fullfilled状态的话,生成的Promise对象(p)也会变成fullfilled状态,
p1,p2,p3三个Promise对象产生的结果会组成一个数组返回给传递给p的回调函数。
如果p1,p2,p3中有一个Promise对象变为rejected状态的话,p也会变成rejected状态,第一个被rejected的对象的返回值会传递给p的回调函数。
Promise.all()方法生成的Promise对象也会有一个catch方法来捕获错误处理,但是如果数组中的Promise对象变成rejected状态时,
并且这个对象还定义了catch的方法,那么rejected的对象会执行自己的catch方法。
并且返回一个状态为fullfilled的Promise对象,Promise.all()生成的对象会接受这个Promise对象,不会返回rejected状态。
回到顶部
async 和 await
主要考察宏任务和微任务,搭配promise,询问一些输出的顺序

原理:async 和 await 用了同步的方式去做异步,async 定义的函数的返回值都是 promise,await 后面的函数会先执行一遍,然后就会跳出整个 async 函数来执行后面js栈的代码

回到顶部
ES6 的 class 和构造函数的区别
class 的写法只是语法糖,和之前 prototype 差不多,但还是有细微差别的,下面看看:

严格模式
类和模块的内部,默认就是严格模式,所以不需要使用use strict指定运行模式。只要你的代码写在类或模块之中,就只有严格模式可用。考虑到未来所有的代码,其实都是运行在模块之中,所以 ES6 实际上把整个语言升级到了严格模式。
不存在提升
类不存在变量提升(hoist),这一点与 ES5 完全不同。
new Foo(); // ReferenceError
class Foo {}
方法默认是不可枚举的
ES6 中的 class,它的方法(包括静态方法和实例方法)默认是不可枚举的,而构造函数默认是可枚举的。细想一下,这其实是个优化,让你在遍历时候,不需要再判断 hasOwnProperty 了
class 的所有方法(包括静态方法和实例方法)都没有原型对象 prototype,所以也没有[[construct]],不能使用 new 来调用。
class 必须使用 new 调用,否则会报错。这是它跟普通构造函数的一个主要区别,后者不用 new 也可以执行。
ES5 和 ES6 子类 this 生成顺序不同
ES5 的继承先 生成了子类实例,再 调用父类的构造函数修饰子类实例。ES6 的继承先 生成父类实例,再 调用子类的构造函数修饰父类实例。这个差别使得 ES6 可以继承内置对象。
ES6可以继承静态方法,而构造函数不能
回到顶部
transform、translate、transition 分别是什么属性?CSS 中常用的实现动画方式
三者属性说明
transform 是指变换、变形,是 css3 的一个属性,和 width,height 属性一样;
translate 是 transform 的属性值,是指元素进行 2D(3D)维度上位移或范围变换;
transition 是指过渡效果,往往理解成简单的动画,需要有触发条件。
这里可以补充下 transition 和 animation 的比较,前者一般定义开始结束两个状态,需要有触发条件;而后者引入了关键帧、速度曲线、播放次数等概念,更符合动画的定义,且无需触发条件

回到顶部
介绍一下rAF(requestAnimationFrame)

  对 rAF 的阐述 MDN 资料

  定时器一直是 js 动画的核心技术,但它们不够精准,因为定时器时间参数是指将执行代码放入 UI 线程队列中等待的时间,如果前面有其他任务队列执行时间过长,则会导致动画延迟,效果不精确等问题。

所以处理动画循环的关键是知道延迟多长时间合适:时间要足够短,才能让动画看起来比较柔滑平顺,避免多余性能损耗;时间要足够长,才能让浏览器准备好变化渲染。
这个时候 rAF 就出现了,采用系统时间间隔(大多浏览器刷新频率是 60Hz,相当于 1000ms/60≈16.6ms),保持最佳绘制效率,不会因为间隔时间过短,造成过度绘制,增加开销;也不会因为间隔时间太长,使用动画卡顿不流畅,让各种网页动画效果能够有一个统一的刷新机制。并且 rAF 会把每一帧中的所有 DOM 操作集中起来,在一次重绘或回流中就完成。

回到顶部
javascript 的垃圾回收机制讲一下
定义:指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束。

像 C 这样的编程语言,具有低级内存管理原语,如 malloc()和 free()。开发人员使用这些原语显式地对操作系统的内存进行分配和释放。
而 JavaScript 在创建对象(对象、字符串等)时会为它们分配内存,不再使用对时会“自动”释放内存,这个过程称为垃圾收集。

内存生命周期中的每一个阶段:
分配内存 —  内存是由操作系统分配的,它允许您的程序使用它。在低级语言(例如 C 语言)中,这是一个开发人员需要自己处理的显式执行的操作。然而,在高级语言中,系统会自动为你分配内在。
使用内存 — 这是程序实际使用之前分配的内存,在代码中使用分配的变量时,就会发生读和写操作。
释放内存 — 释放所有不再使用的内存,使之成为自由内存,并可以被重利用。与分配内存操作一样,这一操作在低级语言中也是需要显式地执行。

四种常见的内存泄漏:全局变量,未清除的定时器,闭包,以及 dom 的引用
全局变量 不用 var 声明的变量,相当于挂载到 window 对象上。如:b=1; 解决:使用严格模式
被遗忘的定时器和回调函数
闭包
没有清理的 DOM 元素引用
回到顶部
对前端性能优化有什么了解?一般都通过那几个方面去优化的?
前端性能优化的七大手段

减少请求数量
减小资源大小
优化网络连接
优化资源加载
减少重绘回流
性能更好的API
webpack优化
前端安全也经常被问到的,常见的有两种——XSS、CSRF,详见前端安全
找到工作前还会不定期补充,未完待续...
原文地址https://www.cnblogs.com/chenwenhao/p/11253403.html

相关文章
|
7天前
|
JavaScript 前端开发 程序员
前端原生Js批量修改页面元素属性的2个方法
原生 Js 的 getElementsByClassName 和 querySelectorAll 都能获取批量的页面元素,但是它们之间有些细微的差别,稍不注意,就很容易弄错!
|
20天前
|
JSON JavaScript 前端开发
[JS]面试官:你的简历上写着熟悉jsonp,那你说说它的底层逻辑是怎样的?
本文介绍了JSONP的工作原理及其在解决跨域请求中的应用。首先解释了同源策略的概念,然后通过多个示例详细阐述了JSONP如何通过动态解释服务端返回的JavaScript脚本来实现跨域数据交互。文章还探讨了使用jQuery的`$.ajax`方法封装JSONP请求的方式,并提供了具体的代码示例。最后,通过一个更复杂的示例展示了如何处理JSON格式的响应数据。
29 2
[JS]面试官:你的简历上写着熟悉jsonp,那你说说它的底层逻辑是怎样的?
|
8天前
|
JSON 前端开发 JavaScript
聊聊 Go 语言中的 JSON 序列化与 js 前端交互类型失真问题
在Web开发中,后端与前端的数据交换常使用JSON格式,但JavaScript的数字类型仅能安全处理-2^53到2^53间的整数,超出此范围会导致精度丢失。本文通过Go语言的`encoding/json`包,介绍如何通过将大整数以字符串形式序列化和反序列化,有效解决这一问题,确保前后端数据交换的准确性。
21 4
|
18天前
|
机器学习/深度学习 自然语言处理 前端开发
前端神经网络入门:Brain.js - 详细介绍和对比不同的实现 - CNN、RNN、DNN、FFNN -无需准备环境打开浏览器即可测试运行-支持WebGPU加速
本文介绍了如何使用 JavaScript 神经网络库 **Brain.js** 实现不同类型的神经网络,包括前馈神经网络(FFNN)、深度神经网络(DNN)和循环神经网络(RNN)。通过简单的示例和代码,帮助前端开发者快速入门并理解神经网络的基本概念。文章还对比了各类神经网络的特点和适用场景,并简要介绍了卷积神经网络(CNN)的替代方案。
|
18天前
|
移动开发 前端开发 JavaScript
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效
于辰在大学期间带领团队参考网易游戏官网的部分游戏页面,开发了一系列前端实训作品。项目包括首页、2021校园招聘页面和明日之后游戏页面,涉及多种特效实现,如动态图片切换和人物聚合效果。作品源码已上传至CSDN,视频效果可在CSDN预览。
29 0
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效
|
23天前
|
JavaScript 前端开发 开发者
前端框架对比:Vue.js与Angular的优劣分析与选择建议
【10月更文挑战第27天】在前端开发领域,Vue.js和Angular是两个备受瞩目的框架。本文对比了两者的优劣,Vue.js以轻量级和易上手著称,适合快速开发小型到中型项目;Angular则由Google支持,功能全面,适合大型企业级应用。选择时需考虑项目需求、团队熟悉度和长期维护等因素。
34 1
|
3月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
16天前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
17天前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
41 4
|
1月前
|
算法 Java 数据中心
探讨面试常见问题雪花算法、时钟回拨问题,java中优雅的实现方式
【10月更文挑战第2天】在大数据量系统中,分布式ID生成是一个关键问题。为了保证在分布式环境下生成的ID唯一、有序且高效,业界提出了多种解决方案,其中雪花算法(Snowflake Algorithm)是一种广泛应用的分布式ID生成算法。本文将详细介绍雪花算法的原理、实现及其处理时钟回拨问题的方法,并提供Java代码示例。
74 2
下一篇
无影云桌面