2021-03-04

**

2021前端面试题笔记

**

1、栈、堆

2、ssr服务器端渲染,Nuxt.js

3、图片转换base64

4、深度遍历,广度遍历

5、空间复杂度,时间复杂度

6、Promises

7、面向对象。

js的面向对象编程,个人理解如下:

编程分为面向过程和面向对象,这是两种思想。
面向过程的软件设计理念:一个程序只是一个函数的集合,或简单的计算机指令列表。
面向对象的软件设计理念:一系列对象相互协作的结果。
个人理解:如果页面上有一只狗,它会叫,它有眼睛,鼻子,年龄,狗毛颜色。
如果是面向过程开发,就是眼睛,鼻子,狗毛颜色,都是对应的一个函数。那么当有三只狗的时候,这些函数因为是面向过程的,所以,还要写三次。
而面向对象是写一个对象,里面有眼睛鼻子狗毛颜色的一些属性,也有叫的方法。
有三只狗的时候,就会调用同一个对象,这三只狗调用的时候,就是分别对这个对象进行了实例化。但这样写相当于精简了代码。

面向对象开发,每个对象都是一个模块,需要的时候调用就可以。

面向对象的三个特点:封装、继承、多态。

(1)封装,即将描述同一个对象的属性和方法定义在一个对象中。

(2)继承,即父对象中的属性和方法被子对象使用。

(3)多态,即同一个对象在不同情况下呈现不同的形态(注意,在 JavaScript中无多态”的概念)。多态有以下两种形式。

重载,即同一方法名,根据传入的参数不同,而执行不同操作。

重写,即子对象在继承父对象的属性或方法后,重新定义一个新的属性或方法以覆盖从父对象中继承的属性或方法。

其中,继承是重点,有以下几种实现方式:

(1)构造函数式继承。

(2)类(原型链)式继承。

(3)组合式继承(混合使用构造函数式和类式)。

(4)寄生式继承。

(5)继承组合式继承(混合使用构造函数式和寄生式)。

(6)原子继承。

(7)多继承。

(8)静态继承。

(9)特性继承。

(10)构造函数拓展式继承。

(11)工厂式继承

8、微任务、宏任务:时间循环的各个阶段

9、箭头函数this,作用域链、js引擎实现。

10、沙盒机制是一种安全机制,用于防止不同应用之间互相访问。
有以下三个特点:
(1)每个应用程序都有自己的存储空间
(2)应用程序不能翻过自己的围墙去访问别的存储空间的内容
(3)应用程序请求的数据都要通过权限检测,假如不符合条件的话,不会被放行。
沙盒目录中包含:Documents、Library、tmp和一个xxx.app程序包。

Document : 存储用户数据,需要备份的信息
Library/Caches : 存储缓存文件,程序专用的支持文件
Library/Preferences : 存储应用程序的偏好设置⽂件
tmp : 存储临时文件,比如:下载的zip包,解压后的再删除
xxx.app : 应用程序包

iTunes在与iPhone同步时,会备份 DocumentsPreferences 目录下的⽂件 。

11、Set、Map数据结构 WeakSet、WeakMap
Set是一个存储无重复值的无序列表的一个数据容器。
Set有add()、delete()、clear()、has()、forEach()等方法。还有size属性。
使用实例:let set = new Set([1,1,2,3,4,4])
WeakSet方法。只接受对象,没有size属性、forEach()方法。
实例:let set = new WeakSet()

Map是存储有序键值对的数据结构。
使用实例:let map = new Map(‘title’,‘hello’) key是title,value是hello
Map有add()、delete()、clear()、has()、forEach()等方法。还有size属性。
Object.is()用来判断两个值是否相等。用法实例:Object.is({a:1}, {a:1}) false
let WeakMap = new WeakMap([[key,‘hello’],[key2,‘world’]]);

12、指针只是指向内存的一个索引;而地址则是内存中确切的位置。
删除指针或者回收指针不会影响地址。指针可以有无数个,地址只有一个。

13、JS的垃圾回收机制。

a、涉及知识点:JS内存、JS引擎。

b、目的:防止内存泄漏。回收不再使用的变量的内存。

c、JS内存的分配机制:

JS内存空间:栈(LIFO)、堆(无序的key-value键值对)、池。

栈存放变量,堆存放对象、池存放常量。

栈(stack):系统自动分配内存空间,可直接访问栈内存中的值,大小固定,存放基础数据类型(Undefined、Null、Boolean、String、Number、Symbol),遵循先进后出原则(LIFO)。

堆(heap):系统动态分配内存空间,不可直接访问堆内存中的位置,只可通过操作对象的引用来访问(可理解为:先从栈中获得该对象的地址指针,再从堆内取得所需的数据),存放引用数据类型(Object、Array、Function)。

栈内有多个对象地址而且都是互相独立的,堆内可能都指向同一个对象。
所以对象的引用是改变的栈内的空间,而不是堆,堆内的实际对象也会因为栈内的指针变量而改变。

JS的内存生命周期:内存分配、内存使用、内存回收。

JS变量的生命周期:局部变量(函数执行结束即释放)、全局变量(浏览器关闭才释放)

JS垃圾回收方式:标记清除(mark and sweep)、引用计数(reference counting)

标记清除:进入环境就标记“进入环境”,离开环境就标记"离开环境",有标记“离开环境”并且没有被引用的变量就被销毁回收。

引用计数:被引用次数为0时就被回收,例外就是对象相互引用形成一个环。

什么是垃圾:没有被引用的对象和被互相引用形成一个环的对象。
栈内存中的对象,只要方法执行结束就会被回收。
堆内存中的对象,只有当没有任何变量引用它时才会被回收。

e、JS引擎:是一个专门处理JavaScript脚本的程序虚拟机,一般会附带在网页浏览器之中。
例如:Google chrome 的JS的解析引擎是V8,IE(Internet Exporer)和微软 (Microsoft Edge)是Chakra,火狐(Mozilla Firefox)是SpiderMonkey。

JS引擎包括:编辑器(源代码编译成AST)、解释器(解析并输出运行结果)、JIT工具(将字节码、AST转换为本地代码)、垃圾回收器和分析工具(profiler)。

JavaScript引擎是程序,我们写的js代码也是程序。如何让程序读懂程序呢?就需要定义规则。ECMAScript就是定义了这一套规则,ECMAScript 262这份文档就定义了JavaScript这门语言的标准,JavaScript就是对ECMAScript的一种实现。

浏览器包括两个引擎:
【1】、渲染引擎:对HTML文档进行解析并将其显示在页面上的工具。

渲染引擎渲染过程:解析HTML以构建DOM树(构建CSSOM树) => 构建Render树 => 布局Render树 => 绘制Render树。

【2】、JS引擎:提供调用接口被渲染引擎使用。

JS引擎需要渲染引擎提供桥接的接口以访问渲染引擎构建的DOM(文档对象模型)树,进而操作DOM,比如JQuery,由于通过复杂低效的接口访问DOM性能低, VUE是通过数据驱动去实现虚拟DOM的数据更新,性能更高。

BOM(浏览器对象模型):window、navigator、screen、history、location。

f、如何解决:减少全局变量、高效重复利用引用数据类型(object、array、function)

14、操作数据的方法总结:
arr.push():数组末尾加,返回的是数组长度。改变原数组。
arr.unshift(): 数组开头加,返回的是数组长度。改变原数组。
arr.shift():数组开头删第一个,返回第一个被删的元素,改变原数组。
arr.pop():数组末尾删最后一个,返回最后一个被删的元素,改变原数组。

new Set():ES6数组去重。实现示例:let newArr = […new Set(arr)] = Array.from(new Set(arr))。
sort():数组元素排序。将元素转换成字符串,比较UTF-16代码单元值(ASCII字符)排序。即按字符顺序进行排序。如果比较数字,需要进行一个排序函数。改变原数组。
reverse():反转数组中的元素。let newArr = arr.reverse();改变原数组。
delete():删除数组元素。let Boolean = delete arr(1);返回的是Boolean值。改变原数组。

Generator函数:生成器对象,next()、return()、throw(),IE不支持。
flat():返回一个可指定深度递归遍历数组,返回一个一维数组(扁平化),let newArr = arr.flat(Infinity)。IE不支持。
flatMap(): map()和flat()的结合。IE不支持。
toString():返回对象的字符串。转换为二进制,16进制等。也可以检测对象类,toString.call([1])=>"[object Array]"

15、JavaScript事件轮询(event Loop)
javaScript运行机制:单线程本质,多线程执行。
主线程、任务队列(执行栈)、宏任务、微任务、
主线程是单线程是指:UI渲染引擎和JavaScript引擎是同一个线程。
宿主环境(浏览器/node)提供的是宏任务(macroTask):setTimeout、setInterval、Event、Ajax、I/O、requestAnimationFrame。
语言标准(JavaScript)提供的是微任务(microTask): Promise、mutationObserver、Process.nextTick

先执行主线程中的任务,在任务队列里分同步任务、异步任务。遇到宏任务放入宏任务队列,微任务放在微任务队列,
事件轮询如下:
web APIs ===> 任务队列(onload、onclick) ===> 执行栈(foo()/query()) ===> web APIs(ajax/setTimeout)

16、回调函数:将一个函数作为参数传入主函数里,在主函数里满足某个条件开始执行作为参数的函数,这个作为参数的函数就是回调函数。回调函数有命名函数和匿名函数作为回调。

17、浅拷贝:栈存储拷贝。
深拷贝:栈堆存储拷贝。开辟新的栈内存、堆内存存储空间。

18、indexDB的理解:
一个对象存储空间,相比于storage、cookie更复杂,其大小取决于硬盘,与数据库相关,可以进行对数据库的增删改查,由于浏览器厂商未达成统一,现在通过window访问需要加前缀,比如window.mozIndexedDB。

19、Symbol原始数据类型,是ES6引入的,表示独一无二的值。
typeof Symbol(‘foo’) === ‘Symbol’ 不能new。
使用场景:const red = Symbol(‘red’) const blue = Symbol(‘red’) red和blue不一样。

20、js沙盒模式(沙箱模式):
(1)和全局变量相关。
(2)执行解析不可信js代码。
(3)隔离执行代码的执行环境。
(4)执行代码的可访问对象要进行限制。
(5)vue服务端渲染,bundle文件。

21、强引用、弱引用区别
强引用:new对象引用,如set、map数据结构。垃圾回收时按照规则回收。
弱引用:用来描述非必须对象,如wakeSet、WakeMap。垃圾回收时不管是否有被引用的对象,都会被回收。

22、CSS Hack:
是为了解决兼容浏览器的一种方法。
(1)、属性级hack,IE7识别和!important,IE6识别_和。firfox不能识别_和*,只能识别!important。
(2)、选择符级hack,IE7识别*+html .class{}、:first-child。IE6识别html .class。
(3)、IE条件注释hack:<!-[if it IE 7]><!
浏览器优先级:firfox<IE7<IE6

23、vue进行SEO优化(Search Engine Optimizition)
目的:提升网页在搜索引擎中
引申:引擎蜘蛛的工作原理:识别meta标签,读取keyword、description的内容;HTML5语义化的标签抓取和分析内容;读取a标签的链接进行跳转,会根据广度优先和深度优先决定;h标签,strong标签、em标签的强调意义。
浏览器的渲染:HTML的解析、DOM的构建、CSSOM解析构建、JavaScript的解析、render Tree的渲染、Render Tree的绘制。

(1)、SSR服务端渲染,Nuxt.js框架,执行 generate 静态化打包
(2)、预渲染prerender-spa-plugin,config.js和main.js进行配置
(3)、使用Phantom.js插件针对爬虫做处理

24、JS的迭代器Iterator是一种接口,为各种不同的数据结构提供统一的访问机制。
在ES6中有三类数据结构原生具备Iterator接口,数组,类数组,Set和Map。这些对象原生部署了Symbol.Iterator接口。
是JS引擎SpiderMonkey的一个特性,可以用for…of替代。.

25、DOM事件流:事件捕获阶段,事件目标阶段,事件冒泡阶段。
事件冒泡是指事件发生的点往父元素上传播。
事件捕获是指事件先在福元素上,然后向下传播到事件发生的点上。
DOM0级事件元素可以绑定多个事件但只执行最后一个,只适合普通事件,例如平时最多的按钮点击事件就是DOM0级事件。
DOM2级事件通过绑定addEventListerner(事件名,事件函数,Boolean) ,
IE是通过绑定attachEvent事件。
Boolean为false是事件冒泡阶段调用,W3C、IE都支持,true是事件捕获阶段调用。
通过removeEventListerner移除事件,但不能移除事件函数是匿名函数的事件。

26、事件委托,是指在父元素上绑定监听事件,来监听子元素上的事件。比如ul、li标签。

27、性能优化:懒加载和预加载。
懒加载就是延迟加载,比如淘宝下滑显示图片,下滑的时候才加载,减少无效资源的加载和缓解服务器的压力。
预加载就是提前加载,某些资源提前加载可以缓解页面空白的现象。服务器压力会增加。

28、mouseenter不支持事件冒泡,IE支持,可能有兼容性问题。mouseleave。
mouseover支持事件冒泡,子元素会被频繁触发,不推荐。mouseout。

29、call、apply、bind的区别:
实例:B.call(A,arg1,arg2)。
定义:调用一个对象的方法,用另一个对象替换当前对象。
相同点:都是改变函数执行上下文的方法(改变this指向的方法),第一个参数就是this要指向的对象,bind返回的是函数,call、apply立刻执行。
区别:call、apply的区别是入参,call(obj,arg1,arg2),apply(obj,[arg1,arg2]),bind(obj,arg1,arg2)()。
call细节,非严格模式:不传参或者第一个参数是undefined、null,this都指向window。严格模式:第一个参数是谁,this就指向谁,第一个参数是null,this指向null,不传参this指向undefined。
obj.call(newobj,arg1,arg2),obj对象里的this指向newobj。

30、clientHight:可是高度height+上下padding。
scrollHight:滚动高度height+上下padding。
offsetHight:可视高度hight++上下padding+上下border-width。
clientTop:容器内部到容器顶部的top偏移量==上border-width。
scrollTop:y轴滚动条到顶部,范围是0~scrollTop-clientTop。
offsetTop:容器到父元素的偏移量top + margin-top + border-top

31、HTML5拖放功能:drag/drop。
draggable 属性设置为true,drag拖动是触发。drop放置时触发。

32、js阻塞原理:性能优化,提升页面加载速度。
浏览器内核分为:渲染引擎、JS引擎。
渲染引擎包括:HTML解析器、CSS解析器、布局、网络、存储、图形、音视频、图片解码器。
defer async 引入script脚本放在head标签内时,延迟加载,defer按顺序加载,async按大小延迟加载。
defer比async更加稳妥。而且defer的优先级比async高,若同时存在。

33、浏览器缓存问题解决方案:
(1)、下载附件时,在url后加上时间戳,“nowTime=new Date().getTime()”或者随机数:“sjs=Math.random()”
(2)、在ajax请求前加上setRequestHeader(“Cache-Control”,“no-cache”)或者加上anyAjaxObj.setRequestHeader(“If-Modified-Since”,“0”)。

34、JS的防抖和节流
主要用来解决scroll事件高频度触发以及页面重新渲染。
防抖(debouncing):在一定时间内,规定事件被触发的次数。不能解决图片下滑懒加载的功能。
节流(throttling):在一定时间内,只允许被触发一次。

35、简述地址栏输入URL到页面整个显示出来,中间的过程。
涉及知识点:OSI参考模型有七层,分别是应用层,表示层,会话层、传输层、网络层、数据链路层、物理层。
在这里插入图片描述
在这里插入图片描述

应用层:用户进程。
传输层:TCP、UDP。
网络层:IP协议。
数据链路层:硬件接口。

在这里插入图片描述

36、ES6的Object方法总结:
(1)、Object.is(value1,value2) 判断两个值是否相等。等同于"==="。不同的是Object.is(+0,-0)=>false。Object.is(NaN,NaN)=>true。
+0 === -0 =>true。NaN === NaN=>false。
(2)、Object.assgin(target,…sources),将源对象的可枚举的属性复制到目标对象上。
注意点:一般将目标对象设为{},不然会改变目标对象的值。
Boolean、Numbe、null、undefined会被忽略。
异常后会打断后续拷贝。
只有字符串的包装对象才有可枚举属性。
(3)、Object.defineProperty(obj,prop,descriptor),这个方法会在对象obj上定义或修改一个新属性prop,并返回此对象。
描述descriptor中有以下几个属性值:configurable指prop属性是否可被删除。
enumerable指该属性prop是否可被枚举。
writable指value指能被赋值运算改变。
get(),getter函数返回值会被当做prop的值。
set(),setter函数在被修改时调用。
实例:Object.defineProperty(obj,‘key’,{configurable:true,writable:true,value:25})
(4)、Object.keys(),返回一个数组,成员是参数对象本身可遍历的属性名的键名数组。key值。元素是字符串。
(5)、Object.values(),返回一个数组,成员是参数对象本身可遍历的属性名的键值数组。
(6)、Object.entries(),返回一个数组,成员是参数对象本身可遍历的属性名的键值对数组。Object.entries({a:‘b’,“d”:12})=>[[“a”, “b”],[ “d”, 12]]
(7)、Object.create(),ES6创建对象的方式,属性在原型下面。例如:let obj = {a:1},let obj1 = Object.create(obj),obj1.proto=>{a: 1}。属性描述符默认为false, 不可修改,不可枚举。关于拷贝,自身可枚举用Object.assign()。拷贝原型上的用Object.create()、Object.assign()、Object.getPrototypeOf()。拷贝get/set,可以用Ojbect.getOwnPropertyDescriptors().
(8)、Object.prototype.hasOwnProperty(),返回Boolean,判断对象自身属性中是否含有指定的属性。let obj = {‘a’:‘1’},obj.hasOwnProperty(‘a’)=>true。
(9)、Object.getOwnPropertyNames(),返回一个数组,成员是参数对象本身可遍历的属性名的键名数组,和Object.keys的区别是Object.keys()只适用可枚举的属性。比如Object.defineProperty(B,‘methodsB’,{enumerable:true,value:‘ff’})

37、proto,prototype的区别:__proto是将对象和对象的原型相连。Function Person(){},let person1 = new Person().person1.proto === Person.prototype =>true。除了在浏览器中,proto是无法访问的。Person.prototye的原型链是Objec.prototype,这就是终极原型对象的尽头。所有对象的valueOf(),toString(),hasOwnProperty()、constructor都是继承于Object.prototype。Object.is(person1.constructor,Person)=>true

38、css sprites雪碧图与base64编码。
css sprites 一次性加载显示出来,不会一张一张慢慢显示。
原理:用到background-image,background-position,background-repeat。
优点:减少HTTP请求,提升网页加载速度,缓解服务器CPU压力。多张小图合成大图,减少字节数总数(大图<多张小图)。不会增加css体积。
缺点:前期需要用ps将图片按照顺序合并到一张图上。经常要变动的图片维护麻烦。
base64 将图片编码成一串字符串。
CRP关键路径渲染,
原理:在解析css文件时解析。
优点:不会有HTTP请求,可减少HTTP请求。避免跨域、缓存、请求头、cookie等问题。
缺点:CSS体积增大,可能会引起CRP关键路径渲染,即CSS渲染阻塞,导致页面空白。CSSOM时间变长。低版本的IE不兼容。

39、解构赋值,IE不支持。 rest…参数解决传入的参数数量不一定。

40、

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值