能够判断出'string','number','boolean','undefined','symbol'
但判断 typeof(null) 时值为 'object'; 判断数组和对象时值均为 'object'javascript
原理是 构造函数的 prototype 属性是否出如今对象的原型链中的任何位置css
function A() {} let a = new A(); a instanceof A //true,由于 Object.getPrototypeOf(a) === A.prototype;
经常使用于判断浏览器内置对象,对于全部基本的数据类型都能进行判断,即便是 null 和 undefinedhtml
用于判断是否为数组前端
ES5 有俩种:var
和 function
ES6 有六种:增长四种,let
、const
、class
和 import
java
注意:let
、const
、class
声明的全局变量不再会和全局对象的属性挂钩webpack
闭包的概念:闭包就是能读取其余函数内部变量的函数。css3
优势:es6
缺点:web
// 第一层为深拷贝 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 }
let arr = [1,1,2,3,4,5,5,6] let arr2 = [...new Set(arr)]
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 },[])
// 这种方法会有一个问题:[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 })
分为三大阶段:捕获阶段--目标阶段--冒泡阶段
事件代理简单说就是:事件不直接绑定到某元素上,而是绑定到该元素的父元素上,进行触发事件操做时(例如'click'),再经过条件判断,执行事件触发后的语句(例如'alert(e.target.innerHTML)')
好处:(1)使代码更简洁;(2)节省内存开销
JavaScript 语言的一大特色就是单线程,同一个时间只能作一件事。单线程就意味着,全部任务须要排队,前一个任务结束,才会执行后一个任务。若是前一个任务耗时很长,后一个任务就不得不一直等着。JavaScript 语言的设计者意识到这个问题,将全部任务分红两种,一种是同步任务(synchronous),另外一种是异步任务(asynchronous),在全部同步任务执行完以前,任何的异步任务是不会执行的。
当咱们打开网站时,网页的渲染过程就是一大堆同步任务,好比页面骨架和页面元素的渲染。而像加载图片音乐之类占用资源大耗时久的任务,就是异步任务。关于这部分有严格的文字定义,但本文的目的是用最小的学习成本完全弄懂执行机制,因此咱们用导图来讲明:
导图要表达的内容用文字来表述的话:
同步和异步任务分别进入不一样的执行"场所",同步的进入主线程,异步的进入 Event Table 并注册函数。当指定的事情完成时,Event Table 会将这个函数移入 Event Queue。主线程内的任务执行完毕为空,会去 Event Queue 读取对应的函数,进入主线程执行。上述过程会不断重复,也就是常说的 Event Loop(事件循环)。
咱们不由要问了,那怎么知道主线程执行栈为空啊?js 引擎存在 monitoring process 进程,会持续不断的检查主线程执行栈是否为空,一旦为空,就会去 Event Queue 那里检查是否有等待被调用的函数。换一张图片也许更好理解主线程的执行过程:
上图用文字表述就是:主线程从"任务队列"中读取事件,这个过程是循环不断的,因此整个的这种运行机制又称为 Event Loop(事件循环)。只要主线程空了,就会去读取"任务队列",这就是 JavaScript 的运行机制。
说完 JS 主线程的执行机制,下面说说常常被问到的 JS 异步中 宏任务(macrotasks)、微任务(microtasks)执行顺序。JS 异步有一个机制,就是遇到宏任务,先执行宏任务,将宏任务放入 Event Queue,而后再执行微任务,将微任务放入 Event Queue,可是,这两个 Queue 不是一个 Queue。当你往外拿的时候先从微任务里拿这个回调函数,而后再从宏任务的 Queue 拿宏任务的回调函数。以下图:
宏任务:总体代码 script,setTimeout,setInterval
微任务:Promise,process.nextTick
Promise.all()方法将多个Promise实例包装成一个Promise对象(p),接受一个数组(p1,p2,p3)做为参数,数组中不必定须要都是Promise对象,可是必定具备Iterator接口,若是不是的话,就会调用Promise.resolve将其转化为Promise对象以后再进行处理。
使用Promise.all()生成的Promise对象(p)的状态是由数组中的Promise对象(p1,p2,p3)决定的。
主要考察宏任务和微任务,搭配promise,询问一些输出的顺序
原理:async 和 await 用了同步的方式去作异步,async 定义的函数的返回值都是 promise,await 后面的函数会先执行一遍,而后就会跳出整个 async 函数来执行后面js栈的代码
class 的写法只是语法糖,和以前 prototype 差很少,但仍是有细微差异的,下面看看:
类和模块的内部,默认就是严格模式,因此不须要使用use strict
指定运行模式。只要你的代码写在类或模块之中,就只有严格模式可用。考虑到将来全部的代码,其实都是运行在模块之中,因此 ES6 实际上把整个语言升级到了严格模式。
类不存在变量提高(hoist),这一点与 ES5 彻底不一样。
new Foo(); // ReferenceError class Foo {}
ES6 中的 class,它的方法(包括静态方法和实例方法)默认是不可枚举的,而构造函数默认是可枚举的。细想一下,这实际上是个优化,让你在遍历时候,不须要再判断 hasOwnProperty 了
ES5 的继承先生成了子类实例,再调用父类的构造函数修饰子类实例。ES6 的继承先 生成父类实例,再调用子类的构造函数修饰父类实例。这个差异使得 ES6 能够继承内置对象。
三者属性说明
transform 是指变换、变形,是 css3 的一个属性,和 width,height 属性同样;
translate 是 transform 的属性值,是指元素进行 2D(3D)维度上位移或范围变换;
transition 是指过渡效果,每每理解成简单的动画,须要有触发条件。
这里能够补充下 transition 和 animation 的比较,前者通常定义开始结束两个状态,须要有触发条件;然后者引入了关键帧、速度曲线、播放次数等概念,更符合动画的定义,且无需触发条件
专门用来作动画,不卡顿,用法和setTimeout同样。对 rAF 的阐述 MDN 资料
定时器一直是 js 动画的核心技术,但它们不够精准,由于定时器时间参数是指将执行代码放入 UI 线程队列中等待的时间,若是前面有其余任务队列执行时间过长,则会致使动画延迟,效果不精确等问题。
因此处理动画循环的关键是知道延迟多长时间合适:时间要足够短,才能让动画看起来比较柔滑平顺,避免多余性能损耗;时间要足够长,才能让浏览器准备好变化渲染。这个时候 rAF 就出现了,采用系统时间间隔(大多浏览器刷新频率是 60Hz,至关于 1000ms/60≈16.6ms),保持最佳绘制效率,不会由于间隔时间太短,形成过分绘制,增长开销;也不会由于间隔时间太长,使用动画卡顿不流畅,让各类网页动画效果可以有一个统一的刷新机制。而且 rAF 会把每一帧中的全部 DOM 操做集中起来,在一次重绘或回流中就完成。
详情:CSS3动画那么强,requestAnimationFrame还有毛线用?
定义:指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束。
像 C 这样的编程语言,具备低级内存管理原语,如 malloc()和 free()。开发人员使用这些原语显式地对操做系统的内存进行分配和释放。
而 JavaScript 在建立对象(对象、字符串等)时会为它们分配内存,再也不使用对时会“自动”释放内存,这个过程称为垃圾收集。
内存生命周期中的每个阶段:
分配内存 — 内存是由操做系统分配的,它容许您的程序使用它。在低级语言(例如 C 语言)中,这是一个开发人员须要本身处理的显式执行的操做。然而,在高级语言中,系统会自动为你分配内在。
使用内存 — 这是程序实际使用以前分配的内存,在代码中使用分配的变量时,就会发生读和写操做。
释放内存 — 释放全部再也不使用的内存,使之成为自由内存,并能够被重利用。与分配内存操做同样,这一操做在低级语言中也是须要显式地执行。
前端安全也常常被问到的,常见的有两种——XSS、CSRF,详见前端安全
2019前端面试系列——CSS面试题
2019前端面试系列——JS面试题
2019前端面试系列——JS高频手写代码题
2019前端面试系列——Vue面试题
2019前端面试系列——HTTP、浏览器面试题