js相关

118 阅读15分钟

- 说一说什么是跨域,怎么解决

因为浏览器出于安全考虑,有同源策略。也就是说,如果协议、域名或者端口有一个不同就是跨域,Ajax 请求会失败。 为来防止CSRF攻击 1.JSONP JSONP 的原理很简单,就是利用 JSONP 使用简单且兼容性不错,但是只限于 get 请求。 2.CORS CORS 需要浏览器和后端同时支持。IE 8 和 9 需要通过 XDomainRequest 来实现。 3.document.domain 该方式只能用于二级域名相同的情况下,比如 a.test.com 和 b.test.com 适用于该方式。 只需要给页面添加 document.domain = 'test.com' 表示二级域名都相同就可以实现跨域 4.webpack配置proxyTable设置开发环境跨域 5.nginx代理跨域 6.iframe跨域 7.postMessage 这种方式通常用于获取嵌入页面中的第三方页面数据。一个页面发送消息,另一个页面判断来源并接收消息

说一说SessionStorage和localStorage还有cookie

共同点:都是保存在浏览器端、且同源的 不同点: 1.cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。 cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下 sessionStorage和localStorage不会自动把数据发送给服务器,仅在本地保存。 2.存储大小限制也不同,cookie数据不能超过4K,sessionStorage和localStorage可以达到5M 3.sessionStorage:仅在当前浏览器窗口关闭之前有效; localStorage:始终有效,窗口或浏览器关闭也一直保存,本地存储,因此用作持久数据; cookie:只在设置的cookie过期时间之前有效,即使窗口关闭或浏览器关闭 4.作用域不同 sessionStorage:不在不同的浏览器窗口中共享,即使是同一个页面; localstorage:在所有同源窗口中都是共享的;也就是说只要浏览器不关闭,数据仍然存在 cookie: 也是在所有同源窗口中都是共享的.也就是说只要浏览器不关闭,数据仍然存在

- Promise是什么,解决了什么,之前怎么实现的

Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。 解决来之前在请求中回调请求产生的回调地狱,使得现在的代码更加合理更加优雅,也更加容易定位查找问题。

- 说说浏览器缓存

缓存可以减少网络 IO 消耗,提高访问速度。浏览器缓存是一种操作简单、效果显著的前端性能优化手段 很多时候,大家倾向于将浏览器缓存简单地理解为“HTTP 缓存”。 但事实上,浏览器缓存机制有四个方面,它们按照获取资源时请求的优先级依次排列如下: Memory Cache Service Worker Cache HTTP Cache Push Cache

缓存它又分为强缓存和协商缓存。优先级较高的是强缓存,在命中强缓存失败的情况下,才会走协商缓存 实现强缓存,过去我们一直用 expires。 当服务器返回响应时,在 Response Headers 中将过期时间写入 expires 字段,现在一般使用Cache-Control 两者同时出现使用Cache-Control 协商缓存,Last-Modified 是一个时间戳,如果我们启用了协商缓存,它会在首次请求时随着 Response Headers 返回:每次请求去判断这个时间戳是否发生变化。 从而去决定你是304读取缓存还是给你返回最新的数据

js数据类型,typeof ,instanceof,类型转换

数据类型: function ,string ,bolean,number,object,null
typeof: 用来判断数据类型,返回值有,string, boolean, number,function ,object,undefined
instanceof 判断该对象是谁的实例
null表示空对象,undefined表示声明了但是为赋值。

闭包:

子函数可以使用父函数中的局部变量

原型,原型链

原型: 对象中固有的__proto__属性,该属性指向对象中的prototype原型属性。
JavaScript中的对象都有一个特殊的 prototype 内置属性,其实就是对其他对象的引用 几乎所有的对象在创建时 prototype 属性都会被赋予一个非空的值,我们可以把这个属性当作一个备用的仓库 当试图引用对象的属性时会出发get操作,第一步时检查对象本身是否有这个属性,如果有就使用它,没有就去原型中查找。一层层向上直到Object.prototype顶层
原型链,当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去他的原型对象里
找这个属性,这个原型对象又会有自己的原型,于是这样一直找下去,也就是原型链的概念。

特点:js对象时通过引用来传递的,我们创建的每一个新对象实体中并没有一份属于自己的原型副本,
当我们修改原型时,与之响应的对象也会继承这一改变。

this指向,new关键字

this对象是执行上下文中的一个属性,他指向最后一次调用这个方法的对象在全局函数中,this等于window
而当函数被作为某个对象调用时,this等于那个对象,在实际开发中,this的指向可以通过4中调用模式来判断
1,函数调用,当一个函数不是一个对象的属性时,直接作为函数来调用时,this指向全局对象。
2,方法调用,如果一个函数作为一个对象的方法来调用时,this指向这个对象。
3,构造函数调用,this指向用new新创建的对象
4,第四种是apply,call,bind调用模式,这3个方法都可以显示指定调用函数的this指向,
apply接收参数的是数组
call接收参数列表
call通过传入一个对象,返回this绑定传入对象的新函数。

继承(含es6),多种继承方式

(1,以原型链的方式来实现继承,缺点是,在包含有引用类型的数据时,会被所有的实例对象所共享容易 造成数据混乱,还有就是在创建子类型的时候不能向吵类型传递参数。 (2,使用借用构造函数方式,通过子类型函数中调用超类型的构造函数来实现的,这种方法解决了不能 向超类型传递参数的缺点,但是它存在一个问题就是无法实现函数方法的复用,并且超类型原型 定义的方法子类型也没有方法访问到。 (3)第三种方式是组合继承,组合继承是将原型链和借用构造函数组合起来使用的一种方式。通过借用构造函数的方式来实现类型的属性的继承,通过将子类型的原型设置为超类型的实例来实现方法的继承。这种方式解决了上面的两种模式单独使用时的问题,但是由于我们是以超类型的实例来作为子类型的原型,所以调用了两次超类的构造函数,造成了子类型的原型中多了很多不必要的属性。 (4)第四种方式是原型式继承,原型式继承的主要思路就是基于已有的对象来创建新的对象,实现的原理是,向函数中传入一个对象,然后返回一个以这个对象为原型的对象。这种继承的思路主要不是为了实现创造一种新的类型,只是对某个对象实现一种简单继承,ES5 中定义的 Object.create() 方法就是原型式继承的实现。缺点与原型链方式相同。 (5)第五种方式是寄生式继承,寄生式继承的思路是创建一个用于封装继承过程的函数,通过传入一个对象,然后复制一个对象的副本,然后对象进行扩展,最后返回这个对象。这个扩展的过程就可以理解是一种继承。这种继承的优点就是对一个简单对象实现继承,如果这个对象不是我们的自定义类型时。缺点是没有办法实现函数的复用。 (6)第六种方式是寄生式组合继承,组合继承的缺点就是使用超类型的实例做为子类型的原型,导致添加了不必要的原型属性。寄生式组合继承的方式是使用超类型的原型的副本来作为子类型的原型,这样就避免了创建不必要的属性。

原生ajax

ajax是一种异步通信的方法,从服务端获取数据,达到局部刷新页面的效果。
过程:

创建XMLHttpRequest对象;
调用open方法传入三个参数 请求方式(GET/POST)、url、同步异步(true/false);
监听onreadystatechange事件,当readystate等于4时返回responseText;
调用send方法传递参数。

事件冒泡、捕获(委托)

事件冒泡指在在一个对象上触发某类事件,如果此对象绑定了事件,就会触发事件,如果没有,就会向这个对象的父级对象传播,最终父级对象触发了事件。
事件委托本质上是利用了浏览器事件冒泡的机制。因为事件在冒泡过程中会上传到父节点,并且父节点可以通过事件对象获取到目标节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件,这种方式称为事件代理。

event.stopPropagation() 或者 ie下的方法 event.cancelBubble = true; //阻止事件冒泡

- ES6新特性

1,ES6引入来严格模式 变量必须声明后在使用 函数的参数不能有同名属性, 否则报错 不能使用with语句 不能对只读属性赋值, 否则报错 不能使用前缀0表示八进制数,否则报错 不能删除不可删除的数据, 否则报错 不能删除变量delete prop, 会报错, 只能删除属性delete global[prop] eval不会在它的外层作用域引入变量 eval和arguments不能被重新赋值 arguments不会自动反映函数参数的变化 不能使用arguments.caller 不能使用arguments.callee 禁止this指向全局对象 不能使用fn.caller和fn.arguments获取函数调用的堆栈 增加了保留字(比如protected、static和interface)

2.关于let和const新增的变量声明

3.变量的解构赋值

4.字符串的扩展 includes():返回布尔值,表示是否找到了参数字符串。 startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。 endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。

5.数值的扩展 Number.isFinite()用来检查一个数值是否为有限的(finite)。 Number.isNaN()用来检查一个值是否为NaN。

6.函数的扩展 函数参数指定默认值

7.数组的扩展 扩展运算符

8.对象的扩展 对象的解构

9.新增symbol数据类型

10.Set 和 Map 数据结构 ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。 Set 本身是一个构造函数,用来生成 Set 数据结构。 Map它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。

11.Proxy Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问 都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。 Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。 Vue3.0使用了proxy

12.Promise Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。 特点是: 对象的状态不受外界影响。 一旦状态改变,就不会再变,任何时候都可以得到这个结果。

13.async 函数 async函数对 Generator 函数的区别: (1)内置执行器。 Generator 函数的执行必须靠执行器,而async函数自带执行器。也就是说,async函数的执行,与普通函数一模一样,只要一行。 (2)更好的语义。 async和await,比起星号和yield,语义更清楚了。async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。 (3)正常情况下,await命令后面是一个 Promise 对象。如果不是,会被转成一个立即resolve的 Promise 对象。 (4)返回值是 Promise。 async函数的返回值是 Promise 对象,这比 Generator 函数的返回值是 Iterator 对象方便多了。你可以用then方法指定下一步的操作。 14.Class class跟let、const一样:不存在变量提升、不能重复声明... ES6 的class可以看作只是一个语法糖,它的绝大部分功能 ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。 15.Module ES6 的模块自动采用严格模式,不管你有没有在模块头部加上"use strict";。 import和export命令以及export和export default的区别

14.Class class跟let、const一样:不存在变量提升、不能重复声明... ES6 的class可以看作只是一个语法糖,它的绝大部分功能 ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。

15.Module ES6 的模块自动采用严格模式,不管你有没有在模块头部加上"use strict";。 import和export命令以及export和export default的区别

- 陈述输入URL回车后的过程

1.读取缓存: 搜索自身的 DNS 缓存。(如果 DNS 缓存中找到IP 地址就跳过了接下来查找 IP 地址步骤,直接访问该 IP 地址。) 2.DNS 解析:将域名解析成 IP 地址 3.TCP 连接:TCP 三次握手,简易描述三次握手 客户端:服务端你在么? 服务端:客户端我在,你要连接我么? 客户端:是的服务端,我要链接。 连接打通,可以开始请求来 4.发送 HTTP 请求 5.服务器处理请求并返回 HTTP 报文 6.浏览器解析渲染页面 7.断开连接:TCP 四次挥手 关于第六步浏览器解析渲染页面又可以聊聊如果返回的是html页面 根据 HTML 解析出 DOM 树 根据 CSS 解析生成 CSS 规则树 结合 DOM 树和 CSS 规则树,生成渲染树 根据渲染树计算每一个节点的信息 根据计算好的信息绘制页面

- 陈述http

基本概念:

HTTP,全称为 HyperText Transfer Protocol,即为超文本传输协议。是互联网应用最为广泛的一种网络协议 所有的 www 文件都必须遵守这个标准。

http特性:

HTTP 是无连接无状态的 HTTP 一般构建于 TCP/IP 协议之上,默认端口号是 80 HTTP 可以分为两个部分,即请求和响应。

http请求:

HTTP 定义了在与服务器交互的不同方式,最常用的方法有 4 种 分别是 GET,POST,PUT, DELETE。URL 全称为资源描述符,可以这么认为:一个 URL 地址 对应着一个网络上的资源,而 HTTP 中的 GET,POST,PUT,DELETE 就对应着对这个资源的查询,修改,增添,删除4个操作。

HTTP 请求由 3 个部分构成,分别是:状态行,请求头(Request Header),请求正文。

HTTP 响应由 3 个部分构成,分别是:状态行,响应头(Response Header),响应正文。

HTTP 响应中包含一个状态码,用来表示服务器对客户端响应的结果。 状态码一般由3位构成:

1xx : 表示请求已经接受了,继续处理。 2xx : 表示请求已经处理掉了。 3xx : 重定向。 4xx : 一般表示客户端有错误,请求无法实现。 5xx : 一般为服务器端的错误。

比如常见的状态码:

200 OK 客户端请求成功。 301 Moved Permanently 请求永久重定向。 302 Moved Temporarily 请求临时重定向。 304 Not Modified 文件未修改,可以直接使用缓存的文件。 400 Bad Request 由于客户端请求有语法错误,不能被服务器所理解。 401 Unauthorized 请求未经授权,无法访问。 403 Forbidden 服务器收到请求,但是拒绝提供服务。服务器通常会在响应正文中给出不提供服务的原因。 404 Not Found 请求的资源不存在,比如输入了错误的URL。 500 Internal Server Error 服务器发生不可预期的错误,导致无法完成客户端的请求。 503 Service Unavailable 服务器当前不能够处理客户端的请求,在一段时间之后,服务器可能会恢复正常。

大概还有一些关于http请求和响应头信息的介绍。

- 数组去重

第一种: 通过ES6新特性Set() 例如: var arr = [1, 2, 3, 1, 2]; var newArr= [...new Set(arr)]

- Set,Map解构

ES6 提供了新的数据结构 Set。 它类似于数组,但是成员的值都是唯一的,没有重复的值。 Set 本身是一个构造函数,用来生成 Set 数据结构。 ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。

对数组排序

第一种方法利用sort方法 第二种利用冒泡排序