在前后端分离的模式下,前后端的域名是不一致的,此时就会发生跨域 访问问题。在请求的过程中我们要想回去数据一般都是 post/get 请求,所以跨域问题出现。
跨域问题来源于 JavaScript 的同源策略,即只有 协议+主机名+端口号 (如存在)相同,则允许相互访问。也就是说 JavaScript 只能访问和操作自己域下的资源,不能访问和操作其他域下的资源。
同源策略 是由 NetScape 提出的一个著名的安全策略。所谓的同源,指 的是协议,域名,端口相同。浏览器处于安全方面的考虑,只允许本域名下的接口交互,不同源的客户端脚本,在没有明确授权的情况下,不能读写对方的资源。
3.什么是 jsonp 工作原理是什么?他为什么不是真正的 ajax?
Jsonp 其实就是一个跨域解决方案。Js 跨域请求数据是不可以的,但是 js 跨域请求 js 脚本是可以的。所以可以把要请求的数据封装成一个 js 语句,做一个方法的调用。跨域请求 js 脚本可以得到此脚本。得到 js 脚本之后会立即执行。可以把数据做为参数传递到方法中。就可以获得数据。从而解决跨域问题。
jsonp 原理:(动态创建 script 标签,回调函数) 浏览器在 js 请求中,是允许通过 script 标签的 src 跨域请求,可以在请求的结果中添加回调方法名,在请求页面中定义方法,就可获取到跨域请求的数据。
为什么不是真正的 ajax?
1、ajax 和 jsonp 这两种技术在调用方式上"看起来"很像,目的也一样,都是请求一个 url,然后把服务器返回的数据进行处理,因此 jquery 和ext 等框架都把 jsonp 作为 ajax 的一种形式进行了封装;
2、但 ajax 和 jsonp 其实本质上是不同的东西。ajax 的核心是通过XmlHttpRequest获取本页内容,而jsonp的核心则是动态添加<script>标签来调用服务器提供的 js 脚本。
3、所以说,其实 ajax 与 jsonp 的区别不在于是否跨域,ajax 通过服务端代理一样可以实现跨域,jsonp 本身也不排斥同域的数据的获取。
4、还有就是,jsonp 是一种方式或者说非强制协议,如同 ajax 一样,它也不一定非要 json 格式来传递数据,如果你愿意,字符换也行,只不过这样不利于 jsonp 提供公开服务。
4.深浅拷贝是什么如何实现?
深拷贝:指针赋值,并且内容拷贝、浅拷贝:只是简单的指针赋值 数组
浅拷贝: 如果是数组,可以使用数组的一些方法实现:slice(),concat()返回一个新数组的特性实现拷贝。用扩展运算符 spread 实现数组深拷贝:
JSON.parse(JSON.stringify())不仅适用于数组还适用于对象。不能拷贝函数,undefined,symbol。
5.为什么 js 是弱类型语言?
弱类型语言实现相对于强类型语言来说的,在强类型语言中,变量类型有多种,比如 int char float Boolean 不同类型相互转换有时需要强制转换,而 jacascript 只有一种类型 var,为变量赋值时会自动判断类型并转换,所以是弱类型语言。
6.For 循环与 map 循环有什么区别 ?
For 遍历对象自身的和继承可枚举的属性,也就是说会包括哪些原型链上的属性。
Map 方法不会对空数组进行检测,map 会返回一个新数组,不会对原数组产生影响。
7.重绘和回流是什么 ?
回流:当 render tree 中的一部分或者全部因为元素的规模尺寸,布局,隐藏等改变而需要重新构建,这就叫回流,每个页面至少需要一次回流,就是在页面第一次加载的时候,这时候一定会发生回流,因为要构建render tree 在回流的时候,浏览器会使渲染树中收到影响的部分失效,并重新构造这部分渲染树,完成回流后,浏览器会重新绘制受影响的部分到屏幕中,这就是重绘当render tree 中的一些元素需要更新属性,而这些属性只是影响元素的 外观,不会影响布局,就叫重绘。
8.箭头函数与普通函数的区别?
箭头函数是匿名函数,不能作为构造函数,不能使用 new
箭头函数不能绑定 arguments,要用 rest 参数解决
箭头函数没有原型属性
箭头函数的 this 永远指向其上下文的 this,
箭头函数不能绑定 this,会捕获其所在的上下文的 this 值,作为自己的 this 值
9.什么是 js 内存泄露?
内存泄漏是指一块被分配的内存既不能使用又不能回收,直到浏览器进程结束
释放内存的方法:赋值为 null
10.你如何对网站的文件和资源进行优化?
1)文件合并(目的是减少 http 请求)
2)文件压缩(目的是直接减少文件下载的体积)
3)使用 cdn 托管资源
4)使用缓存
5)gizp 压缩你的 js 和 css 文件
6)meta 标签优化(title,description,keywords)、heading 标签的优化、alt 优化
7)反向链接,网站外链接优化
11.请简述 ajax 的执行过程 以及常见的 HTTP状态码?
100:这个状态码是告诉客户端应该继续发送请求,这个临时响应是用来通知客户端的,部分的请求服务器已经接受,但是客户端应继续发送求请求的剩余部分,如果请求已经完成,就忽略这个响应,而且服务器会在请求完成后向客户发送一个最终的结果。
200:这个是最常见的 http 状态码,表示服务器已经成功接受请求,并将返回客户端所请求的最终结果。
202:表示服务器已经接受了请求,但是还没有处理,而且这个请求最终会不会处理还不确定。
204:服务器成功处理了请求,但没有返回任何实体内容 ,可能会返回新的头部元信息。
301:客户端请求的网页已经永久移动到新的位置,当链接发生变化时,返回 301 代码告诉客户端链接的变化,客户端保存新的链接,并向新的链接发出请求,已返回请求结果。
404:请求失败,客户端请求的资源没有找到或者是不存在。
500:服务器遇到未知的错误,导致无法完成客户端当前的请求。
503:服务器由于临时的服务器过载或者是维护,无法解决当前的请求。
12.预加载和懒加载的区别,预加载在什么时间加载合适?
预加载是指在页面加载完成之前,提前将所需资源下载,之后使用的时候从缓存中调用;懒加载是延迟加载,按照一定的条件或者需求等到满足条件的时候再加载对应的资源。
两者主要区别是一个是提前加载,一个是迟缓甚至不加载。懒加载对服务器前端有一定的缓解压力作用,预加载则会增加服务器前端压力。
13.Jquery 插入节点的方法?
append() 向每个匹配的元素内部追加内容。
appendTo() 将所有匹配的元素追加到指定元素中,实际上,使用该方
法是颠倒了常规的$(A).append(B)的操作 将 A 追加到 B 中。
prepend() 向每个匹配的元素内部前置内容。
prependTo() 将所有匹配的元素前置到指定的元素中。实际上,使用该 方法是颠倒了常规的$(A).prepend(B)的操作,即不是将 B 前置到 A 中,而是将 A 前置到 B 中。
after() 在每个匹配的元素之后插入内容。
insertAfter() 将所有匹配的元素插入到指定元素的后面。实际上,使用该方法是颠倒了常规的$(A).after(B)的操作,即不是讲 B 插入到 A 后面,而是将 A 插入到 B 后面。
before() 在每个匹配的元素之前插入内容。
insertBefore() 将所有匹配的元素插入到指定的元素的前面。实际上,使用该方法是颠倒了常规的$(A).before(B)的操作,即不是将 B 插入到 A 前面,而是将 A 插入到 B 前面。
14.Js 的函数节流和函数防抖的区别?
函数节流是指一定时间内 js 方法只执行一次。
函数防抖是指频繁触发的情况下,只有足够的空闲时间,才执行代码一次。
函数节流是 声明一个变量当标志位,记录当前代码是否在执行,如果正在执行,取消这次方法执行,直接 return,如果空闲,正常触发方法执行
函数防抖是需要一个延时器来辅助实现,延迟执行需要执行的代码,如果方法多次触发,把上次记录的延迟执行代码用 cleartimeout 清除掉,重新开始,如果计时完毕,没有方法来访问触发,则执行代码。
15.Get 和 post 不同?
Get 是从服务器上获取数据,post 是向服务器传送数据在客户端,get 通过 url 提交数据,数据在 url 中可以看到,post 方式,数据放在 html header 中提交 安全性问题 Get 提交数据最多只能有 1024 字节,post 没有限制
16.js数据类型?
JS的数据类型有8种。
在ES5的时候,我们认知的数据类型确实是 6种:Number、String、Boolean、undefined、object、Null。
ES6 中新增了一种 Symbol 。这种类型的对象永不相等,即始创建的时候传入相同的值,可以解决属性名冲突的问题,做为标记。
谷歌67版本中还出现了一种 bigInt。是指安全存储、操作大整数。(但是很多人不把这个做为一个类型)。
JS数据类型:Object 中包含了哪几种类型?其中包含了Date、function、Array等(这三种比较常用)。
17.for in、Object.keys()区别?哪个要用于遍历原型链上的属性?
for-in 是javaScript中最常见的迭代语句,常常用来枚举对象的属性。某些情况下,可能按照随机顺序遍历数组元素;而Object.keys(),可以返回以对象的属性为元素的数组。数组中属性名的顺序跟使用for-in遍历返回的顺序是一样的。
二者遍历的数量是不同的,for-in 不但可以枚举自身属性,也可以枚举继承自原型链上的属性,Object.keys()只可以枚举自身属性。for-in会遍历原型链上的属性,而Object.keys不会。
18.什么是事件委托?为什么这样做?
它还有一个名字叫事件代理,事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。
为什么这样做呢?通过事件委托可以减少事件处理程序数量,这样就能大大的减少与dom的交互次数,提高性能;
19.NaN == NaN 的结果是什么?为什么?
NaN == NaN 的执行结果是 false。因为JavaScript规定,NaN表示的是非数字,但是这个非数字也是不同的,因此 NaN 不等于 NaN,两个NaN永远不可能相等。
20.说一下你对Promise的了解?说说你对Promise的原理的理解?
Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。所谓promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。
1.Promise.all(),一个失败后,其他的还返回吗?
不会返回,promise.all()失败的时候只返回最先被reject失败状态的那个实例对象的值
2.Promise.all()、Promise.race()区别?‘
两者都是可以同时调用多个promise实现,Promise.all可以将多个实例组装成一个新的实例,成功的时候返回一个成功数组,失败的时候则返回最先被reject失败状态的值;其中有一个实例不成功则返回reject;race()是赛跑的意思,也就是说Promise.race([p1, p2, p3])里面的结果哪个获取的快,就返回哪个结果,不管结果本身是成功还是失败。
21.简单介绍原型链?
所有对象都有自己的原型对象(prototype)。一方面,任何一个对象,都可以充当其他对象的原型;另一方面,由于原型对象也是对象,所以它也有自己的原型。因此,就会形成一个“原型链”(prototype chain)最终都可以上溯到Object.prototype Object.prototype对象有没有它的原型呢?回答Object.prototype的原型是null。null没有任何属性和方法,也没有自己的原型。因此,原型链的尽头就是null。
22.await后面可以是一个普通的函数吗?
可以,但是其结果会转化为promise的resolve状态。
23.es6的set、map介绍?
set和map都是es6新增的数据结构。其中set是一个类数组结构,值是唯一的,没有重复的值。map类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。如果你需要“键值对”的数据结构,Map 比 Object 更合适。
24.简述一下对闭包理解?
闭包:在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。一般情况下,在我们认知当中,如果一个函数结束,函数的内部所有东西都会释放掉,还给内存,局部变量都会消失。但是闭包是一种特殊情况,如果外函数在结束的时候发现有自己的临时变量将来会在内部函数中用到,就把这个临时变量绑定给了内部函数,然后自己再结束。经常用闭包来实现面向对象编程
一个函数和它的周围状态的引用捆绑在一起的组合,是一个可以读取其他函数内部变量的函数,在js中只有函数内部的函数才可以读取该函数内部的变量,因此,闭包可以是一个函数中返回的函数。
闭包的好处:可以读取其他函数你内部的变量,并将其一直保存在内存中。
坏处: 可能会造成内存泄露或者内存溢出。
25.const、let、var的区别?
var 声明的变量属于函数作用域,let 和 const 声明的变量属于块级作用域;
var 存在变量提升现象,而 let 和 const 没有此类现象;
var 变量可以重复声明,而在同一个块级作用域,let 变量不能重新声明,const 变量不能修改
Var 不存在暂时性死区,而let const存在暂时性死区。