前端面试基础总结(个人整理_彦超)

前端面试基础总结

1、跨域解决办法:

1、 通过jsonp跨域
2、 document.domain + iframe跨域
3、 location.hash + iframe
4、 window.name + iframe跨域
5、 postMessage跨域
6、 跨域资源共享(CORS)
7、 nginx代理跨域
8、 nodejs中间件代理跨域
9、 WebSocket协议跨域

2、同源策略下有几个标签不受限制:



    

3、JS代码压缩原理:

基于Base62 encode压缩方式
	简单来说就是将相同的单词进行压缩,具体为将所有单词抽取出来作为一个词典,
	然后将源代码中表示单词的地方改为引用词典的下标

4、Object.create()

创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。
Object.create(null)在该对象上没有继承 Object.prototype 原型链上的属性或者方法
	如:toString(), hasOwnProperty()等方法
    正确的写法:Object.create(Object.prototype);   

5、canvas绘图环境

通过调试canvas对象的getContext()方法。

6、进制转换:

Number.toString(radix)

	这个函数只能将十进制数字转换为任意进制的字符串形式,同样,radix表示进制,取值2~36。
		(10).toString(2)//"1010"转2进制
		(1000).toString(36)//"rs" 转36进制

Number.parseInt(string , radix)

	这个是把字符串(只能由字母和数字组成),这个只能是由低进制转高进制,
		Number.parseInt('010',8)//8
		Number.parseInt('20',2)//NaN

7、koa2洋葱模型:

回调函数的嵌套
	compose函数中将`context`一路传下去给中间件
	将`middleware`中的下一个中间件`fn`作为未来`next`的返回值
	我们在使用use的时候将middleware存在一个数组里面,当拦截到请求时执行callback方法,callback中调用了compose,
	compose方法使用递归执行中间件,遍历完成返回promise.resolve(),实际最后执行的代码也是promise嵌套的形式。

8、Array.of和new Array:

1、Array.of(3)输出[3];new Array(3)输出[undefined,undefined,undefined,]    

9、DNS在进行域名解析时

DNS在进行域名解析时使用UDP,但是在域名服务器之间传输时使用的是TCP

10、CSS权重:

!important>行内样式>id选择器>类选择器>标签选择器>通配符>继承,color可继承则为最高    

11、:before和:after的使用方法:

在类选择器后面用:before和:after连接,表示输出在标签前后的行内样式,
如果加上display:block输出在标签上下的块级样式,也可用于清楚浮动

12、闭包的定义:

    1、函数内部的变量为私有变量,外部不能访问,但是函数内部的函数可以访问,
	   闭包就是在函数内返回一个函数,使得在全局下可以通过函数内返回的函数访问到函数的变量
    2、函数执行形成不能被释放的私有栈内存

闭包的使用场景:

	    1、使用场景一:给对象设置私有变量并且利用特权方法去访问私有属性
	    2、封装相关功能集
    优缺点:
        1.保护函数内的变量安全,加强了封装性
        2.在内存中维持一个变量(用的太多就变成了缺点,占内存)
    原因:
        1.在闭包的作用域链中引用了html元素未释放内存
        2.出现了循环引用    

13、文件传输

1、FormData(二进制文件信息 提交为文件格式)

		文件名需要通过md5加密+时间戳+hash进行处理,产生唯一的文件名,使用FormData()

2、base64编码(流信息 提交为表单格式)

		let file='表单id'.files[0]
		let file_=new FileReader()
		file_.readAsDataURL(file)   获取文件base64编码
		   //file_.readAsDataBuffer(file)也可以转换成ArryBuffer格式
		file_.onload=e=>{
			console.log(e.target.result)//拿到编码
		}   

大文件上传

1、blob切片(blob.prototype.slice)

	   同时发送请求(利用http可以多个并发传递6~7)
	   都上传之后向服务器发送合并请求(两次请求)
	   chunk:文件切片
	   filename:切片的名字 hash-数字后缀
	   传输接片文件的时候为提交为文件格式,传输合并请求时为表单格式

前端静态文本下载

	纯文本:  down_.href = window.URL.createObjectURL(new Blob(["Hello World"]));
	对象  :	 var obj_blob = new Blob([JSON.stringify([1, 2, 3], null, 2)])
		     URL.createObjectURL(obj_blob)

14、null 与 undefined:

JavaScript 中,null 是一个可以被分配的值,设置为 null 的变量意味着其无值。
而 undefined 则代表着某个变量虽然声明了但是尚未进行过任何赋值。

15、Loader和Plugin的不同?

不同的作用

  1、Loader直译为"加载器"。Webpack将一切文件视为模块,但是webpack原生是只能解析js文件,
		   如果想将其他文件也打包的话,就会用到loader。 所以Loader的作用是让webpack
		   拥有了加载和解析非JavaScript文件的能力。
  2、Plugin直译为"插件"。Plugin可以扩展webpack的功能,让webpack具有更多的灵活性。 
	       在 Webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,
		   在合适的时机通过 Webpack 提供的 API 改变输出结果。

不同的用法

  1、Loader在module.rules中配置,也就是说他作为模块的解析规则而存在。 类型为数组,每一项都是一个Object,
	   里面描述了对于什么类型的文件(test),使用什么加载(loader)和使用的参数(options)
  2、Plugin在plugins中单独配置。 类型为数组,每一项是一个plugin的实例,参数都通过构造函数传入。

16、对象类型:

普通对象-Object 数组对象-Array 正则对象-RegExp 日期对象-Date 数学函数-Math 函数对象-Function   

17、事件冒泡(Event Bubbling) :

Event Bubbling 即指某个事件不仅会触发当前元素,还会以嵌套顺序传递到父元素中。
直观而言就是对于某个子元素的点击事件同样会被父元素的点击事件处理器捕获。

18、事件流被分为3个阶段:

捕获阶段,目标阶段,冒泡阶段   

19、如果存在多个事件:

document.onclick=function(){}后注册的事件会覆盖先注册的事件,
使用addEventListener(type,listener,useCapture)则不会,
useCapture:默认为false,事件冒泡从下往上逐级打印,true时相反

20、V8 中执行一段JS代码的整个过程:

1、生成了 AST (类对象类型)
2、将 AST 通过 V8 的解释器(也叫Ignition)转换为字节码
3、在执行字节码的过程中,如果发现某一部分代码重复出现,那么 V8 将它记做热点代码(HotSpot),
   然后将这么代码编译成机器码保存起来,这个用来编译的工具就是V8的编译器,代码执行的时间越久,那么执行效率会越来越高
//通过解释器逐行解释代码,省去了一次性将全部的字节码都转换成机器码大大降低了内存的压力

21、对象的遍历

for...in  								可枚举属性  实例属性  原型属性
Object.keys() 							可枚举属性  实例属性   
Object.getOwnPropertyNames() 不可枚举属性+可枚举属性			原型属性
Reflect.ownKeys()			 不可枚举属性+可枚举属性  实例属性	原型属性 Symbol类型属性

22、window.open && window.location

	window.location.search(获取当页面参数"?ww=xx&ww=xx")
	window.location.href(获取当前页面地址)
	window.open(url, name, [strWindowFeatures]);
			url === 要在新打开的窗口中加载的URL。
			name === 新窗口的名称。
			strWindowFeatures === 一个可选参数,列出新窗口的特征(大小,位置,滚动条等)作为一个DOMString。
			
	*外链用了 target="_blank",新页面能通过window.opener获取到来源页面的window对象 CSRF 攻击
			解决方案:加上rel="noopener"或者rel="noreferrer"。这样新窗口的window.openner就是null了,
			而且会让新窗口运行在独立的进程里,不会拖累原来页面的进程		

23、require.context():

	如果遇到从一个文件夹引入很多模块的情况,可以使用require.context(),
	它会遍历文件夹中的指定文件,然后自动导入,使得不需要每次显式的调用import导入模块
	require.context():
		可以使用 require.context() 方法来创建自己的(模块)上下文。
			这个方法有 3 个参数:
				要搜索的文件夹目录
				是否还应该搜索它的子目录
				以及一个匹配文件的正则表达式。
				
	require.context("./test", false, /\.test\.js$/);
	//(创建了)一个包含了 test 文件夹(不包含子目录)下面的、所有文件名以 `.test.js` 结尾的、
	// 能被 require 请求到的文件的上下文。
	
	require.context模块导出(返回)一个(require)函数
		导出的方法有 3 个属性: resolve, keys, id。
		resolve 接受一个参数request,request为test文件夹下面匹配文件的相对路径
		keys 返回匹配成功模块的名字组成的数组
		id 是上下文模块里面所包含的模块 id

24、事件循环:

(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。
	那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。

25、Class 和构造函数的区别:

1. 不存在变量提升 
2. 方法默认是不可枚举的 
3. class 必须使用 new 调用  
4. ES6可以继承静态方法,而构造函数不能   

26、MVVM模式:

1、M就是Model模型层,存的一个数据对象。
2、V就是View视图层,所有的html节点在这一层。
3、VM就是ViewModel,它通过data属性连接Model模型层,通过el属性连接View视图层。    

27、垃圾回收机制:

栈内存:
 按照执行顺序,也就是上下文切换之后,栈顶的空间会自动被回收
v8引擎的堆垃圾回收机制:
	新生代内存:64 位和 32 位系统下分别为 32MB 和 16MB
 	新生代中的变量如果经过多次回收后依然存在,那么就会被放入到老生代内存中
	新生代的对象主要通过 Scavenge算法 进行垃圾回收。
	老生代的对象主要通过进行标记-清除进行垃圾回收:
		首先会遍历堆中的所有对象, 对它们做上标记,然后对于代码环境中使用的变量以及被强引用的变量取消标记,
		剩下的就是要删除的变量了,在随后的清除阶段对其进行空间的回收。
引发内存碎片的问题?
	存活对象的空间不连续对后续的空间分配造成障碍,V8在清除阶段结束后,把存活的对象全部往一端靠拢。(最耗时间)		   
	为了降低全堆垃圾回收带来的停顿时间,回收方式为增量标记(incremental marking)。

Map和WeakMap,WeakMap只能以复杂数据类型作为key,并且key值是弱引用,对于垃圾回收更加友好。	

28、position:sticky:

position:relative 和 position:fixed 两种定位功能于一体的特殊定位,且position:sticky元素的任意父节点的 
overflow 属性必须是 visible    

29、CORS原理

CORS原理只需要向响应头header中注入Access-Control-Allow-Origin,这样浏览器检测到header中的
Access-Control-Allow-Origin,则就可以跨域操作了,CORS需要浏览器和服务器同时支持。IE浏览器不能低于IE10。
简单请求
 HEAD GET POST HTTP头部信息不超出几个字段
   Content-Type字段类型是application/x-www-form-urlencoded、multipart/form-data、text/plain
非简单请求
   请求方法是PUT或DELETE,Content-Type字段类型是application/json  

30、四种类型的常见 JavaScript 内存泄露:

1:意外的全局变量 
2:被遗忘的计时器或回调函数 
3:脱离 DOM 的引用 
4:闭包     

31、数组的数据存储*:

初始化空数组时,使用快数组,快数组使用连续的内存空间,当数组长度达到最大时,JSArray 会进行动态的扩容,
以存储更多的元素,相对慢数组,性能要好得多。当数组中 hole 太多时,会转变成慢数组,即以哈希表的方式
( key-value 的形式)存储数据,以节省内存空间。

两种存储方式

 fast:是 V8 实现的一个类似于数组的类,它表示一段连续的内存,可以使用索引直接定位。
	   新创建的空数组默认就是快数组。当数组满(数组的长度达到数组在内存中申请的内存容量最大值)的时候,
	   继续 push 时, JSArray 会进行动态的扩容,以存储更多的元素。
 slow:以哈希表的形式存储在内存空间里,它不需要开辟连续的存储空间,
	   但需要额外维护一个哈希表,与快数组相比,性能相对较差。      

存储方式转换

fast 转变为 slow

1、当加入的索引值 index 比当前容量 capacity 差值大于等于 1024 时
2、快数组新容量是扩容后的容量 3 倍之多时
	例:var arr = [1, 2, 3]
		arr[2000] = 10;
		当往 arr 增加一个 2000 的索引时,arr 被转成慢数组。节省了大量的内存空间

slow 转变为 fast

当慢数组的元素可存放在快数组中且长度在 smi 之间且仅节省了50%的空间,则会转变为快数组
数组进行push操作时
	申请新的长度内存空间
	将数组拷贝到新的数组中
	把新数组放到当前length位置
	数组的length+1
	返回 length

32、对象进行比较:

通过JSON.stringify()转为字符串,在进行比较,或者递归,或者Deep Equal模组方法

33、前端登录方案:

session: 1、客户端访问login接口,服务器收到后校验信息,正确后会在服务器端存储一个sessionId和session的映射关系
	     2、服务器端返回response,并且将sessionId以set-cookie的方式发送到客户端,这样sessionId就存在了客户端。
	     3、客户端发送非登录请求时,服务端就能通过cookie中的sessionId找到对应的session来知道这次请求是谁发的
token: 1、客户端访问login接口,服务器收到后校验信息,正确后返回一个包含用户信息的token
	   2、客户端拿到token后,每次请求将token加入http请求的header中
单点登录(SingleSign-On,SSO):在多个应用系统中,只需要登录一次,就可以访问其他相互信任的应用系统。  

34、前端性能监控

performance
memory字段代表JavaScript对内存的占用。
navigation字段统计的是一些网页导航相关的数据:
	redirectCount:重定向的数量(只读),但是这个接口有同源策略限制,即仅能检测同源的重定向;
	type 返回值应该是0,1,2 中的一个。分别对应三个枚举值:
		0 : TYPE_NAVIGATE (用户通过常规导航方式访问页面,比如点一个链接,或者一般的get方式)
		1 : TYPE_RELOAD (用户通过刷新,包括JS调用刷新接口等方式访问页面)
		2 : TYPE_BACK_FORWARD (用户通过后退按钮访问本页面)
最重要的是timing字段的统计数据,它包含了网络、解析等一系列的时间数据。
	var time = performance.timing
	performance.getEntries()
	'重定向时间:' + (time.redirectEnd - time.redirectStart) / 1000
	'DNS解析时间:' + (time.domainLookupEnd - time.domainLookupStart) / 1000
	'TCP完成握手时间:' + (time.connectEnd - time.connectStart) / 1000
	'HTTP请求响应完成时间:' + (time.responseEnd - time.requestStart) / 1000
	'onload事件时间:' + (time.loadEventEnd - time.loadEventStart) / 1000

34.1、首屏和白屏时间如何计算

原生: onload 事件
ios :webViewDidFinishLoad 事件
android :onPageFinished 事件

方法1:当页面的元素数小于x时,则认为页面白屏。比如“没有任何内容”,可以获取页面的DOM节点数,判断DOM节点数少于某个阈值X,则认为白屏。
方法2:当页面出现业务定义的错误码时,则认为是白屏。比如“网络或服务异常”。 
方法3:当页面出现业务定义的特征值时,则认为是白屏。比如“数据加载中”。

35、块级元素:

~

(1)总是从新行开始
(2)高度,行高、外边距以及内边距都可以控制。
(3)宽度默认是容器的100%
(4)可以容纳内联元素和其他块元素。

36、行内元素:

(1)和相邻行内元素在一行上。
(2)高、宽无效,但水平方向的padding和margin可以设置,垂直方向的无效。
(3)默认宽度就是它本身内容的宽度。
(4)行内元素只能容纳文本或则其他行内元素。(a特殊 a里面可以放块级元素 )  

37、行内元素:

(1)和相邻行内元素(行内块)在一行上,但是之间会有空白缝隙。
(2)默认宽度就是它本身内容的宽度。
(3)高度,行高、外边距以及内边距都可以控制。     

38、重绘(repaint):

 当元素样式的改变不影响布局时,浏览器将使用重绘对元素进行更新,此时由于只需要UI层面的重新像素绘制,因此 损耗较少

39、回流(reflow):

 当元素的尺寸、结构或触发某些属性时,浏览器会重新渲染页面,称为回流。
 此时,浏览器需要重新经过计算,计算后还需要重新页面布局,因此是较重的操作。会触发回流的操作
 当我改变了元素的一个样式会导致浏览器发生回流或重绘时 ,它会进入一个渲染队列 ,然后浏览器继续往下看,
 如果下面还有样式修改 ,那么同样入队 ,直到下面没有样式修改 ,浏览器会按照渲染队列批量执行来优化重排过程,
 一并修改样式 ,这样就把本该4次的回流优化为1次 

40、JSON.parse():

 JSON.parse(JSON.stringify(c,['title'])),JSON.stringify只选取数组内的进行格式化     

41、cdn

cdn 也叫内容分发网络,cdn就是通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,
	使得提高用户访问响应速度和命中率。

42、js中i++与++i的区别:

使用i++时,i先将自身的值赋值给变量a,然后再自增1
使用++i时,i先将自身的值自增1,再将自增后的值赋值给变量a

43、怪异盒子模型:

1、元素的宽度和高度指的是元素内容的宽度和高度,而在怪异的盒子模型中宽度和高度还包含了 padding 和 border。
2、行内元素在怪异盒子模型中设置高度会生效

44、监听页面位置

event.clientX,event.clientY表示点击事件发生时候的位置
x轴:pageXOffset
y轴:pageYOffset

懒加载:

第一种

	获取屏幕可视窗口高度:document.documentElement.clientHeight
	获取观测元素相对于文档顶部的距离:element.offsetTop
	获取可视窗口距离文档顶部的距离即滚动条的距离:document.documentElement.scrollTop
	offsetTop - scrollTop - clientHeight <= 0(该元素出现)

第二种

	Element.getBoundingClientRect()方法
	   方法返回的一组矩形的集合,就是该元素的 CSS 边框大小,位置
	function isInSight(el){
		const bound = el.getBoundingClientRect();
		const clientHeight = window.innerHeight;
		return bound.top <= clientHeight + 100;
	}

45、promise

promise是js中的一个对象,用于生成可能在将来产生结果的值且返回一个promise对象

promise 可以有三种状态,一旦确定就不能返回:
    pending:初始状态,既不是成功也不是失败
    fulfilled:意味着操作完全成功
    rejected:意味着操作失败  

catch和reject

Promise.then的第二个参数捕捉不了‘异常捕获’和‘冒泡错误’,只能由catch语句进行捕获,
并且reject是用来抛出异常的,catch是用来处理异常的;

46、javascript会阻塞dom的解析

当解析过程中遇到
                    
                    

你可能感兴趣的:(前端面试基础总结(个人整理_彦超))