首页 / 面试 / 2021---前端面试准备
2021---前端面试准备
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了2021---前端面试准备,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含8069字,纯文字阅读大概需要12分钟。
内容图文
![2021---前端面试准备](/upload/InfoBanner/zyjiaocheng/988/b91b1dd42e514501a028b766655f4ab2.jpg)
1.什么是浏览器同源政策?
我对浏览器的同源政策的理解是,一个域下的 js 脚本在未经允许的情况下,不能够访问 另一个域的内容。这里的同源的指的是两个域的协议、域名、端口号必须相同,否则则不属于同 一个域。同源政策主要限制了三个方面:
第一个是当前域下的 js 脚本不能够访问其他域下的 cookie、localStorage 和 indexDB。
第二个是当前域下的 js 脚本不能够操作访问操作其他域下的 DOM。
第三个是当前域下 ajax 无法发送跨域请求。
同源政策的目的主要是为了保证用户的信息安全,它只是对 js 脚本的一种限制,并不是 对浏览器的限制,对于一般的 img、或者 script 脚本请求都不会有跨域的限制,这是因为这些操作都不会通过响应结果来进行可能 出现安全问题的操作。
2.如何解决跨域?
解决跨域的方法我们可以根据我们想要实现的目的来划分。
首先我们如果只是想要实现主域名下的不同子域名的跨域操作,我们可以使用设置 document.domain 来解决。
(1)将 document.domain 设置为主域名,来实现相同子域名的跨域操作,这个时候主域名下 的 cookie 就能够被子域名所访问。同时如果文档中含有主域名相同,子域名不同的 iframe 的话,我们也可以对这个 iframe 进行操作。
如果是想要解决不同跨域窗口间的通信问题,比如说一个页面想要和页面的中的不同源的 iframe 进行通信的问题,我们可以使用 location.hash 或者 window.name 或者 postMessage 来解决。
(2)使用 location.hash 的方法,我们可以在主页面动态的修改 iframe 窗口的 hash 值, 然后在 iframe 窗口里实现监听函数来实现这样一个单向的通信。因为在 iframe 是没有办法 访问到不同源的父级窗口的,所以我们不能直接修改父级窗口的 hash 值来实现通信,我们可 以在 iframe 中再加入一个 iframe ,这个 iframe 的内容是和父级页面同源的,所以我们可 以 window.parent.parent 来修改最顶级页面的 src,以此来实现双向通信。
(3)使用 window.name 的方法,主要是基于同一个窗口中设置了 window.name 后不同源的 页面也可以访问,所以不同源的子页面可以首先在 window.name 中写入数据,然后跳转到一 个和父级同源的页面。这个时候级页面就可以访问同源的子页面中 window.name 中的数据了, 这种方式的好处是可以传输的数据量大。
(4)使用 postMessage 来解决的方法,这是一个 h5 中新增的一个 api。通过它我们可以实 现多窗口间的信息传递,通过获取到指定窗口的引用,然后调用 postMessage 来发送信息, 在窗口中我们通过对 message 信息的监听来接收信息,以此来实现不同源间的信息交换。如果 是像解决 ajax 无法提交跨域请求的问题,我们可以使用 jsonp、cors、websocket 协议、 服务器代理来解决问题。
(5)使用 jsonp 来实现跨域请求,它的主要原理是通过动态构建 script 标签来实现跨域 请求,因为浏览器对 script 标签的引入没有跨域的访问限制 。通过在请求的 url 后指定一 个回调函数,然后服务器在返回数据的时候,构建一个 json 数据的包装,这个包装就是回调 函数,然后返回给前端,前端接收到数据后,因为请求的是脚本文件,所以会直接执行,这样我 们先前定义好的回调函数就可以被调用,从而实现了跨域请求的处理。这种方式只能用于 get 请求。
(6)使用 CORS 的方式,CORS 是一个 W3C 标准,全称是"跨域资源共享"。CORS 需要浏览器 和服务器同时支持。目前,所有浏览器都支持该功能,因此我们只需要在服务器端配置就行。浏 览器将 CORS 请求分成两类:简单请求和非简单请求。对于简单请求,浏览器直接发出 CORS 请 求。具体来说,就是会在头信息之中,增加一个 Origin 字段。Origin 字段用来说明本次请 求来自哪个源。服务器根据这个值,决定是否同意这次请求。对于如果 Origin 指定的源,不 在许可范围内,服务器会返回一个正常的 HTTP 回应。浏览器发现,这个回应的头信息没有包 含 Access-Control-Allow-Origin 字段,就知道出错了,从而抛出一个错误,ajax 不会收 到响应信息。如果成功的话会包含一些以 Access-Control- 开头的字段。非简单请求,浏览 器会先发出一次预检请求,来判断该域名是否在服务器的白名单中,如果收到肯定回复后才会发 起请求。
(7)使用 websocket 协议,这个协议没有同源限制。
(8)使用服务器来代理跨域的访问请求,就是有跨域的请求操作时发送请求给后端,让后端代 为请求,然后最后将获取的结果发返回。
3.js 的几种模块规范?
js 中现在比较成熟的有四种模块加载方案。
第一种是 CommonJS 方案,它通过 require 来引入模块,通过 module.exports 定义模块的 输出接口。这种模块加载方案是服务器端的解决方案,它是以同步的方式来引入模块的,因为在 服务端文件都存储在本地磁盘,所以读取非常快,所以以同步的方式加载没有问题。但如果是在 浏览器端,由于模块的加载是使用网络请求,因此使用异步加载的方式更加合适。
第二种是 AMD 方案,这种方案采用异步加载的方式来加载模块,模块的加载不影响后面语句的 执行,所有依赖这个模块的语句都定义在一个回调函数里,等到加载完成后再执行回调函数。 require.js 实现了 AMD 规范。
第三种是 CMD 方案,这种方案和 AMD 方案都是为了解决异步模块加载的问题,sea.js 实现 了 CMD 规范。它和 require.js 的区别在于模块定义时对依赖的处理不同和对依赖模块的执行 时机的处理不同。
第四种方案是 ES6 提出的方案,使用 import 和 export 的形式来导入导出模块。这种方案 和上面三种方案都不同。
4.ES6 模块与 CommonJS 模块、AMD、CMD 的差异?
1.CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。 CommonJS 模块输出的是值的拷贝,也就是说,一旦输出一个值,模块 内部的变化就影响不到这个值。ES6 模块的运行机制与 CommonJS 不一 样。JS 引擎对脚本静态分析的时候,遇到模块加载命令 import,就会生 成一个只读引用。等到脚本真正执行时,再根据这个只读引用,到被加载 的那个模块里面去取值。
2.CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。 CommonJS 模块就是对象,即在输入时是先加载整个模块,生成一个对 象,然后再从这个对象上面读取方法,这种加载称为“运行时加载”。而 ES6 模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就 会生成。
5.JavaScript 中的作用域与变量声明提升?
变量提升的表现是,无论我们在函数中何处位置声明的变量,好像都被提升到了函数的首部,我 们可以在变量声明前访问到而不会报错。造成变量声明提升的本质原因是 js 引擎在代码执行 前有一个解析的过程,创建了执行上下文,初始化了一些代码执行时需要用到的对象。当我们访 问一个变量时,我们会到当前执行上下文中的作用域链中去查找,而作用域链的首端指向的是当 前执行上下文的变量对象,这个变量对象是执行上下文的一个属性,它包含了函数的形参、所有 的函数和变量声明,这个对象的是在代码解析的时候创建的。这就是会出现变量声明提升的根本 原因。
6.哪些操作会造成内存泄漏?
第一种情况是我们由于使用未声明的变量,而意外的创建了一个全局变量,而使这个变量一直留 在内存中无法被回收。
第二种情况是我们设置了 setInterval 定时器,而忘记取消它,如果循环函数有对外部变量 的引用的话,那么这个变量会被一直留 在内存中,而无法被回收。
第三种情况是我们获取一个 DOM 元素的引用,而后面这个元素被删除,由于我们一直保留了对 这个元素的引用,所以它也无法被回收。
第四种情况是不合理的使用闭包,从而导致某些变量一直被留在内存当中。
7.js 的事件循环是什么?
js 是单线程运行的,在代码执行的时候,通过将不同函数的执行上下文压入执行栈中来 保证代码的有序执行。在执行同步代码的时候,如果遇到了异步事件,js 引擎并不会一直等待 其返回结果,而是会将这个事件挂起,继续执行执行栈中的其他任务。当异步事件执行完毕后, 再将异步事件对应的回调加入到与当前执行栈中不同的另一个任务队列中等待执行。任务队列可 以分为宏任务对列和微任务对列,当当前执行栈中的事件执行完毕后,js 引擎首先会判断微任 务对列中是否有任务可以执行,如果有就将微任务队首的事件压入栈中执行。当微任务对列中的 任务都执行完成后再去判断宏任务对列中的任务。
微任务包括了 promise 的回调、node 中的 process.nextTick 、对 Dom 变化监听的 MutationObserver。
宏任务包括了 script 脚本的执行、setTimeout ,setInterval ,setImmediate 一类的定 时事件,还有如 I/O 操作、UI 渲 染等。
8.深浅拷贝
浅拷贝指的是将一个对象的属性值复制到另一个对象,如果有的属性的值为引用类型的话,那么 会将这个引用的地址复制给对象,因此两个对象会有同一个引用类型的引用。浅拷贝可以使用 Object.assign 和展开运算符来实现。
深拷贝相对浅拷贝而言,如果遇到属性值为引用类型的时候,它新建一个引用类型并将对应的值 复制给它,因此对象获得的一个新的引用类型而不是一个原有类型的引用。深拷贝对于一些对象 可以使用 JSON 的两个函数来实现,但是由于 JSON 的对象格式比 js 的对象格式更加严格, 所以如果属性值里边出现函数或者 Symbol 类型的值时,会转换失败。
9.箭头函数和普通函数的区别
a. 箭头函数和普通函数的样式不同,箭头函数语法更加简洁、清晰,箭头函数是=>定义函数,普通函数是function定义函数。
b. 箭头函数会捕获其所在上下文的 this 值,作为自己的 this 值,定义的时候就确定并固定了。
c. 箭头函数不能作为构造函数使用,也不能使用new关键字(因为箭头函数没有自己的this,它的this其实是继承了外层执行环境中的this,且this指向永远不会改变,作为构造函数其的this要是指向创建的新对象)。
d. 箭头函数没有自己的arguments。在箭头函数中访问arguments实际上获得的是外层局部(函数)执行环境中的值。
e. call、apply、bind 并不会影响其 this 的指向。
f. 箭头函数没有原型prototype。
g. 箭头函数不能当作 Generator 函数,不能使用 yield 关键字
内容总结
以上是互联网集市为您收集整理的2021---前端面试准备全部内容,希望文章能够帮你解决2021---前端面试准备所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。