收集的问答

new

new 关键字在 JavaScript 中用于调用构造函数,通过 new 关键字调用构造函数可以创建一个新的对象。构造函数可以看作是用来初始化对象的特殊函数,它会为新对象设置属性和方法。当使用 new 关键字和构造函数一起调用时,会创建一个空对象,并将这个空对象绑定到构造函数中的 this 关键字。然后构造函数中的代码会初始化这个对象的属性和方法,最终返回这个新的对象。通过这种方式我们可以轻松地创建多个拥有相似属性和方法的对象,实现了代码的重用和结构的清晰化。”

Foo明明只是一个函数,可是为什么new Foo()执行后会突然返回一个对象呢?
我们从结果出发可以推断出,既然返回了一个对象,那么这事肯定和对象有关系。

实际上new帮我们做了这样几件事:

  1. 帮我们创建了一个空对象,例如:obj;
  2. 将空对象原型的内存地址__proto__指向函数的原型对象;(这里涉及到了原型链的知识)
  3. 利用函数的call方法,将原本指向window的绑定对象this指向了obj。(这样一来,当我们向函数中再传递实参时,对象的属性就会被挂载到obj上。)
  4. 利用函数返回对象obj。
function Foo(name) {
    this.name = name;
    return this;
}
var obj = {};
obj.__proto__ = Foo.prototype;
// Foo.call(obj, 'mm');
var foo = Foo.call(obj, 'mm');
console.log(foo);

 收集的问答_第1张图片

https://www.cnblogs.com/buildnewhomeland/p/12797537.html

垃圾回收机制

垃圾回收机制
作用:清除不在使用的对象,腾出内存空间

  • 对象不再被引用的时候是垃圾;
  • 对象不能从根上访问到时也是垃圾;

引用计数法 用了+1没用–1 =0就会触发垃圾回收机制 有bug循环的时候不会为0一直不会回收 
标记清除法 所有对象为0从根对象开始遍历存货的为1 为0的清除

jsonp跨域原理

jsonp是一种跨域通信的手段,它的原理其实很简单:

  1. 首先是利用script标签的src属性来实现跨域。

  2. 通过将前端方法作为参数传递到服务器端,然后由服务器端注入参数之后再返回,实现服务器端向客户端通信。

  3. 由于使用script标签的src属性,因此只支持get方法

前端-多线程处理Web Workers

前端-多线程处理Web Workers - 知乎

Echarts

 title:{}//标题组件
        tooltip:{},//提示框组件
        yAxis:[],//y轴
        xAxis:[],//x轴
        legend:{},//图例组件
        grid:{},//内绘网格
        toolbox:{},//工具
        series:[],//数据有关
        calculable:true//可计算特性

        其中,颜色标注的三部分是成功绘制一个Echarts图表至少包含的部分。

Echarts常用配置项_echarts配置项_zhangxiaobai___的博客-CSDN博客

echarts自适应
当窗口的大小改变时,ECharts 的图表容器也会随之改变,从而影响图表的大小。通过使用 resize 函数,可以重新绘制图表,从而实现自适应图表大小。

使用 resize()函数
resize0函数是ECharts API提供的函数,接受一个重绘数据的参数,该参数可以是“true”或“false”。当参数为“true”时,将重新绘制图表;当参数为“false”时,不会重新绘制图表。

项目两小时未动未发送请求,退出登录

场景 vue
设置 请求的token在请求头中 请求后最新的token在返回头中

java后台服务 需要拦截器 每次请求查看前端heards里边有没有你设置的token如果有而且没有过期是正确的 那就重新生成最新的token 放在返回的heards里边

在vue的main.js中写入拦截器 拦截所有请求 查看返回的heards里边是否存在token 如果存在更新你本地的token

methods: {
	testTime() {
            this.currentTime = new Date().getTime(); //更新当前时间
            if (this.currentTime - parseInt(localStorage.getItem('lastTime')) > this.timeOut) { //判断是否超时(超时自动退出登录)
                this.cleanAllCache();  //清除所有缓存数据
                //下面就可以按自己的方式跳转到登录页
                window.location.href = `${process.env.VUE_APP_OAUTH_URL}${this.OAUTH}logout?redirect_uri=${window.location.origin}${this.FOLDER_SUFFIX}`;
            }
        },
        setLastTime() {
            localStorage.setItem('lastTime', new Date().getTime().toString());//更新操作时间
        }
}
created() {
	//保存上次进去的时间戳
	this.setLastTime();
	//用定时器监听是否长时间未操作
	window.setInterval(this.testTime, 5 * 1000);
}

微信小程序分层

微信小程序的底层架构原理,及如何做性能优化_小程序分层_浮游本尊的博客-CSDN博客

git代码回滚

拜托,不要再问我Git如何回滚代码 - 知乎

使用git log命令,查看分支提交历史,确认需要回退的版本
使用git reset --hard commit_id命令,进行版本回退
使用git push origin命令,推送至远程分支
回退上个版本:git reset --hard HEAD^ 

【注:HEAD是指向当前版本的指针,HEAD^表示上个版本,HEAD^^表示上上个版本】

reset和revert都可以用来回滚代码。但他们是有区别的,准确来说,reset是用来"回退"版本,而revert是用来"还原"某次或者某几次提交。

$set原理

Vue.set()是将set函数绑定在Vue构造函数上,this.$set()是将set函数绑定在Vue原型上
set函数接收三个参数分别为 target、key、val,其中target的值为数组或者对象
我们平时调用普通数组的push、pop等方法是调用的Array原型上面定义的方法, arrJs的原型是指向Array.prototype,也就是说 arrJs.__proto__ == Array.prototype 。
但是在vue的数组中,我们发现arrVue的原型其实不是指向的Array.prototype,而是指向的一个对象,这个对象上面只有7个push、pop等方法,并且这个对象的原型才是指向的Array.prototype。所以我们在vue中调用数组的push、pop等方法时其实不是直接调用的数组原型给我们提供的push、pop等方法,而是调用的这个对象给我们提供的push、pop等方法,因为vue对数组进行了处理让我们调用数组的方式是响应式的

数组的实现原理
首先if判断当前target是不是数组,并且key的值是有效的数组索引。然后将target数组的长度设置为target.length和key中的最大值,我们发现这里直接调用了target.splice(key, 1, val),splice也是vue提供的7个方法中的一种,Vue.set数组实现的原理:其实Vue.set()对于数组的处理其实就是调用了splice方法

对象的实现原理
先判断如果key本来就是对象中的一个属性,并且key不是Object原型上的属性。说明这个key本来就在对象上面已经定义过了的,直接修改值就可以了,可以自动触发响应,vue给响应式对象都加了一个 __ob__ 属性,Observer 实例,如果一个对象有这个 __ob__ 属性,那么就说明这个对象是响应式对象,我们修改对象已有属性的时候就会触发页面渲染,真正处理对象的地方。 defineReactive(ob.value, key, val) 的意思是给新加的属性添加依赖,以后再直接修改这个新的属性的时候就会触发页面渲染。

Vuex中mutation为什么是同步的action为什么是异步

如果我们在mutation中写了异步,commit在触发mutation事件时,异步的回调函数不知道是什么时候执行的,所以在devtools中难以追踪变化

actions 可以做异步操作,但是并不是直接修改数据,而是通过提交mutations 里面的方法

父组件操作子组件的方法

ref 

打开弹窗
    
    //父组件使用子组件,写上ref=""
	

//父组件methods
	parentOpenDialog() {
	  this.$nextTick(() => {
	    this.$refs["dialog"].openDialog();
	  });
	},
//子组件
openDialog() {
      this.dialogVisible = true;
    }

通过组件的$emit、$on方法

 
        

//父组件
 methods: {
        handleClick() {
               this.$refs.child.$emit("childmethod")    //子组件$on中的名字
        },
    }
//子组件
mounted() {
        this.$nextTick(function() {
            this.$on('childmethods', function() {
                console.log('我是子组件方法');
            });
        });
     },

微信小程序获取appId

let appId=wx.getAccountInfoSync().miniProgram.appId

asyan await

  • async/await 更加优雅的异步编程的写法
    1.它是消灭异步回调的终极武器
    2.它是同步语法,也就是用同步的写法写异步的代码
  • 分别使用 .then 和 await 来获取结果
  • 区别
    1.await 完全没有回调函数
    2.await 是同步写法,异步操作
    3.await 后面不仅仅可以接 promise对象,还可以接 async 函数

async/await的使用方法 - 简书

mixin

Vue 混入(mixin)详细介绍(可复用性、全局混入)_vue mixin_前端不释卷leo的博客-CSDN博客

一.什么是mixins(混入)? mixins是对vue组件的一种扩展,将一些公用的常用数据或者方法,构建一个可被混入的数据结构,被不同的vue组件进行合并,就可以在不同的vue组件中使用相同的方法或者基础数据。

二.作用:
1.更高效的实现组件内容的复用
2.将组件内部data,method等与父组件相应内容进行合并,相当于在引入后,父组件的各种属性,方法进行了扩充
3.对数据,对象进行合并,要以组件为优先

三.本质:
其实就是javaScript的深拷贝 对"对象"的"值"的传递,复制,合并
类似于js中封装的一些公用的方法

this.setDate的原理和限制

this.setData 是一个用于修改页面数据的函数。它的作用是将传入的对象的属性和值应用到小程序页面的数据对象上,并触发页面的重新渲染。

改变 this.data是同步,换句话说,若直接修改 this.data 而不调用 this.setData方法,是无法改变页面的状态的,还会造成数据不一致

当逻辑层data数据渲染到界面的时候,逻辑层的数据需要经过系统层,当系统层接收到这个逻辑层的数据后

系统层在把数据转发给渲染层,然后在渲染层展示出来,在这个过程当中是异步的

setData 将数据从逻辑层发送到视图层是异步,同时改变对应的this.data的值是同步,它并不是实时的,这也导致了必须要考虑性能的因素

本地存储数据不是响应式的如何变成响应式

 由于他不是一个具有属性的对象

首先尝试经过重写localStorage的方法来修复上面的demo,以追踪那些组件实例请求了localstorage的数据项。

Provide和inject

为了避免重复声明props 、一般用于封装组件库,在父组件中使用 provide 抛出数据,可在任意隔代组件下直接使用 inject 获取数据、实现页面刷新 

本身不是响应式的vue2函数返回一个对象可以通过写成对象形式,或者函数形式变成响应式的函数形式的话可以用计算属性去处理一下直接返回结果,Vue3可以通过ref和reactive

provide/inject 不是可响应的
provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的

实现全局传递

provide/inject 只能从祖先传递给后代,但是可以通过在App.vue绑定provide,所有的子组件就都能注入inject,从而达到全局传递。

data() {
     return {
        message:"hello",
        obj:{
           message:"hello"
        }
 },
provide(){
    return{
        message:()=>this.message,
        obj:this.obj
    }
}

inject:['message']
//inject:['obj']

实现页面刷新

1 . 用vue-router重新路由到当前页面,页面是不进行刷新的
2 . 采用window.reload(),或者router.go(0)刷新时,整个浏览器进行了重新加载,闪烁,体验不好

那我们怎么做呢?
跟上面的原理差不多,我们只在控制路由的组件中写一个函数(使用 v-if 控制 router-view 的显示隐藏,这里的原理不作赘述),然后把这个函数传递给后代,然后在后代组件中调用这个方法即可刷新路由啦。

//app.vue

export default {
 name: 'App',
 provide(){
  return{
   reload:this.reload
  }
 },
 data(){
  return{
   isShowRouter:true,
  }
 },
 methods:{
  reload(){
   this.isShowRouter = false;
   this.$nextTick(()=>{
    this.isShowRouter = true;
   })
  }
 }
}
//后代组件
export default {
 inject:['reload'], 
}

插槽区别 作用域插槽特点

匿名插槽
在父组件中   子组件引用的中间也有内容 有代码  父组件可以决定里面html代码的样式 还有数据内容
子组件   使用  slot 插槽标签  可以上父组件传来的内容进行展示 至于在哪里展示 由子组件决定

具名插槽
这个和匿名插槽 区别就是这个是由名字  在标签上  加一个slot 属性 起一个自定义的名字
在子组件中    引用的时候 我们 需要在 slot标签上加上 一个  name属性 名字 就是我们在父组件中自定义的那个名字

作用域插槽
子组件可以通过作用域插槽的方式把数据传递给父组件,父组件插槽使用 是父组件引用子组件中的数据 

什么叫做内容分发  说实话这个问题很模糊 想回答的准确点确实有点难
一个通俗点的回答就是 父组件的数据和子组件的模板配合起来使用就是内容分发 

使用keep-alive缓存的组件需要重新渲染怎么处理

keep-alive 是 Vue 的内置组件,当它包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。keep-alive 是一个抽象组件:它自身不会渲染成一个 DOM 元素,也不会出现在父组件链中。

优点
在组件切换过程中 把切换出去的组件保留在内存中,防止重复渲染DOM,减少加载时间及性能消耗,提高用户体验性

举个栗子:
当我们从首页–>列表页–>商详页–>再返回,这时候列表页应该是需要keep-alive

从首页–>列表页–>商详页–>返回到列表页(需要缓存)–>返回到首页(需要缓存)–>再次进入列表页(不需要缓存),这时候可以按需来控制页面的keep-alive

在路由中设置keepAlive属性判断是否需要缓存

beforeRouteEnter
activated
beforeRouteEnter
每次组件渲染的时候,都会执行beforeRouteEnter

beforeRouteEnter(to, from, next){
    next(vm=>{
        console.log(vm)
        // 每次进入路由执行
        vm.getData()  // 获取数据
    })
},
activated
在keep-alive缓存的组件被激活的时候,都会执行activated钩子

activated(){
   this.getData() // 获取数据
},
注意:服务器端渲染期间acvtived不被调用。

vue的内置组件

Vue内置组件 - 简书

Sass Less编译成css原理

Sass和Less学习_less和sass怎么定义变量_秋榆枫的博客-CSDN博客

意思大概就是less是css的超集,因此在less中转换为css节点是比较慢的
原理主要分析:
less 是预编译处理器,所以会在编译前进行处理成css

  • 首先less 会转换为ast(抽象语法树)语法
  • 然后遍历转换后所有的节点
  • 最后再形成css树
  • Less 使用 @ 符号声明变量
  • Sass/Scss 使用 $ 符号声明变量

vuex存储和本地存储区别

  • 1.区别:vuex存储在内存,localstorage(本地存储)则以文件的方式存储在本地,永久保存;sessionstorage( 会话存储 ) ,临时保存。localStorage和sessionStorage只能存储字符串类型,对于复杂的对象可以使用ECMAScript提供的JSON对象的stringify和parse来处理。

  • 2.应用场景:vuex用于组件之间的传值,localstorage则主要用于不同页面之间的传值。

  • 3.永久性:当刷新页面时vuex存储的值会丢失,localstorage不会。注:很多同学觉得用localstorage可以代替vuex, 对于不变的数据确实可以,但是当两个组件共用一个数据源(对象或数组)时,如果其中一个组件改变了该数据源,希望另一个组件响应该变化时,localstorage无法做到响应式,vuex可以绑定数据响应式。
    Vuex数据状态持久化的使用场景

  • 1、购物车
    比如你把商品加入购物车后,没有保存到后台的情况下,前端来存,就可以通过这种方式vuex+localStorage(sessionStorage)。

  • 2、会话状态
    授权登录后,token就可以用Vuex+localStorage(sessionStorage)来存储。

关于cookie与本地 存储的区别的问题.
1. cookie在浏览器和服务器间来回传递.而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存.
2. cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下.存储大小限制也不同,cookie数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识.sessionStorage和localStorage 虽然也有存储大小的限制

promise方法

promise.all()该方法用于将多个Promise实例,包装成一个新的Promise实例。返回的数组结果顺序不会改变,即使P2的返回要比P1的返回快,顺序依然是P1, P2。 Promise.all成功返回成功数组,失败返回失败数据,一但失败就不会继续往下走

需要特别注意的是,Promise.all获得的成功结果的数组里面的数据顺序和Promise.all接收到的数组顺序是一致的,即p1的结果在前,即便p1的结果获取的比p2要晚。这带来了一个绝大的好处:在前端开发请求数据的过程中,偶尔会遇到发送多个请求并根据请求顺序获取和使用数据的场景,使用Promise.all毫无疑问可以解决这个问题。

Promise.race是赛跑的意思,也就是说Promise.race([p1, p2, p3])里面的结果哪个获取的快,就返回哪个结果,不管结果本身是成功还是失败

使用场景: Promise.all和Promise.race都是有使用场景的。 有些时候我们做一个操作可能得同时需要不同的接口返回的数据,这时我们就可以使用Promise.all; 有时我们比如说有好几个服务器的好几个接口都提供同样的服务,我们不知道哪个接口更快,就可以使用Promise.race,哪个接口的数据先回来我们就用哪个接口的数据

href 与 src?

href (Hypertext Reference)指定网络资源的位置,从而在当前元素或者当前文档和由当前属性定义的需要的锚点或资源之间定义一个链接或者关系。(目的不是为了引用资源,而是为了建立联系,让当前标签能够链接到目标地址。) src source(缩写),指向外部资源的位置,指向的内容将会应用到文档中当前标签所在位置。

href与src的区别
1、请求资源类型不同:href 指向网络资源所在位置,建立和当前元素(锚点)或当前文档(链接)之间的联系。在请求 src 资源时会将其指向的资源下载并应用到文档中,比如 JavaScript 脚本,img 图片;
2、作用结果不同:href 用于在当前文档和引用资源之间确立联系;src 用于替换当前内容;
3、浏览器解析方式不同:当浏览器解析到src ,会暂停其他资源的下载和处理,直到将该资源加载、编译、执行完毕,图片和框架等也如此,类似于将所指向资源应用到当前内容。这也是为什么建议把 js 脚本放在底部而不是头部的原因。

js的变量提升

在js中,变量和函数的声明会被提升到最顶部执行 函数提升高于变量的提升 函数内部如果用var声明了相同名称的外部变量,函数将不再向上寻找 匿名函数不会提升

Vue 中操作 data 中数组的方法中哪些可以触发视图更新

push()、pop()、shift()、unshift()、splice()、sort()、reverse()这些方法会改变被操作的数组; filter()、concat()、 slice()这些方法不会改变被操作的数组,返回一个新的数组; 以上方法都可以触发视图更新。

利用索引直接设置一个数组项,例:this.array[index] = newValue

直接修改数组的长度,例:this.array.length = newLength

以上两种方法不可以触发视图更新;

this.$set(this.array,index,newValue)

this.array.splice(index,1,newValue)

可以用 this.array.splice(newLength)

说一下你在 Vue 中踩过的坑

1、第一个是给对象添加属性的时候,直接通过给 data 里面的对象添加属性然后赋值,新添加的属性不是响应式的

【解决办法】通过 Vue.set(对象,属性,值)这种方式就可以达到,对象新添加的属性是响应式的

1、在 created 操作 dom 的时候,是报错的,获取不到 dom,这个时候实例 Vue实例没有挂载

【解决办法】通过:Vue.nextTick(回调函数进行获取)

Vue 组件 data 为什么必须是函数

1、每个组件都是 Vue 的实例。

2、组件共享 data 属性,当 data 的值是同一个引用类型的值时,改变其中一

个会影响其他

3、组件中的 data 写成一个函数,数据以函数返回值形式定义,这样每复用一次组件,就会返回一份新的 data,类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据。而单纯的写成对象形式,就使得所有组件实例共用了一份 data,就会造成一个变了全都会变的结果。

Object.defineProperty 和 Proxy 的区别(必会)

1)Proxy 的优势如下:

Proxy 可以直接监听对象而非属性;

Proxy 可以直接监听数组的变化;

Proxy 有多达 13 种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等

等是 Object.defineProperty 不具备的;

Proxy 返 回 的 是 一 个 新 对 象 , 我 们 可 以 只 操 作 新 的 对 象 达 到 目 的 , 而Object.defineProperty 只能遍历对象属性直接修改;

Proxy 作为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准的性能红利;

2)Object.defineProperty 的优势如下:

兼容性好,支持 IE9,而 Proxy 的存在浏览器兼容性问题,而且无法用 polyfill

磨平

get和post区别

1.get一般是获取数据,post一般是提交数据
2.get参数会放在url上,所以安全性比较差,post是放在body中
3.get请求时会被缓存,post请求不会被缓存
4.get请求刷新服务器或退回是没有影响的,post请求退回时会重新提交数据
5.get请求会被保存在浏览器历史记录中,post不会
6.get请求只能进行url编码,post请求退回时会重新提交数据

css

css不会阻塞dom树的解析 css会阻塞dom树的渲染 css加载会阻塞后面js的执行

vue3异步组件

Suspense vue3的异步组件 #xxxx===v-solt 缩写 涩丝pen次


        

Echarts地图配置

注册地图series 先在echats里面下载地图数据json然后引入 ruai久丝T map

onMouted(()=>{
    //基于准备好的dom,初始化echarts实例
    var myChart = echarts.init(chart.value);
    //注册可用地图
    echarts.registerMap('china'.地图数据);
    //使用刚指定的配置项和数据显示图表。
    myChart.setOption(option);
    window.addEventListener('resize',()=>{
        myChart.resize()
    })
})

Echarts

1.常用组件有那些
title标题组件 show text link
toolbox工具栏 导出图片 数据视图 切换 缩放 show orient feature tooltip tigger 触发类型
markPoint 图标标线
markLine图标的标线

解决刷新后二次加载路由

matcher 咩缺

const router=createRouter()
export function resetRouter(){
    const newRouter = createRouter()
    router.matcher = newRouter.matcher
}

动态路由

?

语义化的理解

在写HTML页面结构时所用的标签有意义 头部用head hei得 主体用main 妹 底部用foot

如何判断页面是否语义化 把css去掉如果能够清晰的看出来页面结构,显示内容较为正常

为什么要选择语义化 1.让html结构更加清晰明了 2.方便团队协作,利于开发 3.有利于爬虫和SEO 4.能够让浏览器更好的解析代码 5.给用户带来更好的体验

解决了移动端那些兼容问题

1.移动端字体小于12px时异常显示 应该先把整体放大一倍,然后再用transform进行缩小
2.IOS下input输入框在输入引文首字母默认大写
3.禁止IOS识别长串数字为电话 添加meta属性

了解过JWT吗?

JSON web Token 通过JSON形式作为在web应用中的令牌,可以在各方之间安全的把信息作为JSON对象传输,信息传输,授权

JWT的认证流程

1.前端把账号密码发送给后端的接口
2.后端核对账号密码成功后,把用户id等其他信息作为JWT 负载,把它和头部分别进行base64编码拼接后签名,形成一个JWT(token)
3.前端每日请求时都会把JWT放在HTTP请求头的Authorization字段内
4.后端检查是否存在,如果存在就验证JWT的有效性 (签名是否正确,token是否过期)
5.验证通过后后端使用JWT中包含的用户信息进行其他的操作,并返回对应结果

优点 简洁 包含性 包含了很多用户信息 因为token是JSON加密的形式保存在客户端,所以JWT是跨语言的,原则上是任何web形式都支持

svg格式了解多少

基于XML语法格式的图像格式,可缩放矢量图,其他图像是基于像素的,SVG是属于对图像形状的描述,本质是文本文件,体积小,并且不管放大多少倍都不会失真

1.SVG可直接插入页面中,成为DOM一部分,然后用JS或css进行操作

2.SVG可作为文件被引入

3.SVG可以转为base64引入页面

说一下浏览器的缓存策略

强缓存(本地缓存) 协商协议(弱缓存)

强缓:不发起请求,直接使用缓存里的内容,浏览器把js,css,image等存到内存中,下次用户访问直接从内存中取,提高性能。

协缓:需要像后台发送请求,通过判断来决定是否使用协商缓存,如果请求内容没有变化,则返回304,浏览器就用缓存里的内容

强缓存的触发:

HTTP1.0:时间戳响应标头

HTTP1.1:Cache-Control响应标头

协商缓存触发:

HTTP1.0:请求头:if-modified-since 响应头: last-modified

HTTP1.1:请求头: if-none-match 响应头: Etag

说一下什么是同源策略

http:// www. aaa.com:8080/index/vue.js

协议 子域名 主域名 端口号 资源

同源策略是浏览器的核心,如果没有这个策略就会遭受到

主要指的就是协议+域名+端口号三者一致,若其中一个不一样则不是同源,会产生跨域

三个允许跨域加载资源的标签:img link script

跨域是可以发送请求,后端也会正常返回结果,只不过这个结果被浏览器拦截了

这些可以解决跨域问题 JSONP CORS websocket 反向代理

无感登录

1.在相应其中拦截,判断token返回过期后,调用刷新token的接口

2.后端返回过期时间,前端判断token的过期时间,去调用刷新token的接口

3.写定时器,定时刷新token接口

流程

1.登录成功后保存token 和 refresh_token

2.在响应拦截器中对401状态码引入刷新token的api方法调用

3.替换保存本地新的token

4.把错误对象里token替换

5.再次发送未完成的请求

6.如果refresh_token过期了,判断是否过期,过期了就清楚所有token重新登录

Vue中数据持久化

localStorage

vuex-persistedstate 坡c丝听

注意Vuex本身做不到,需要通过vuex-persistedstate插件去做持久化存储

find和filter的区别

区别一:返回的内容不同
    filter 返回是新数组
    find   返回具体的内容
区别二:
    find :匹配到第一个即返回
    filter : 返回整体(没一个匹配到的都返回)

some和every的区别

some  ==》 如果有一项匹配则返回true
every ==》 全部匹配才会返回true

如何统一监听vue组件报错

在App中写一个errorCaptured函数 k耶不缺

errerCaptured(err,vm,info){
    //err 具体错误信息
    //vm 错误发生的组件
    //info 错误信息(指出哪一个地方报的错)
    console.log(err,vm,info)
}

vue.config.errorHandler

接收三个参数:错误、触发错误的组件实例、指定错误源类型的信息字符串。

app.config.errorHandler = (err, instance, info) => {
  // handle error, e.g. report to a service
}

它可以从以下来源捕获错误:

  • 组件渲染

  • 事件处理程序

  • 生命周期钩子

  • setup()函数

  • Watchers

  • 自定义指令钩子

  • 过渡钩子

eventBus实现原理

订阅发布

手写一个订阅发布怎么设计

定义一个对象a 一个用来声明on 一个用来调用emit

let a={
    list:[]
    on:(fnName,fn)=>{
    	this.list.push({
            Name:fnName,
            fn:fn
        })
	}
},
emit:(fnName,"参数")=>{
    this.list.filer(item=>item.name==fnName)[0].fn("chan'shu")
}

自己实现一个vuex

使用eventBus

vue中为什么是this.num不是this.data.num

vue做了一层代理 添加到原型上 extend执行data合并

this

根据函数调用的方式不同,this指向也不同

1.以函数形式调用this是window

2.以方法形式调用,this是调用方法的对象

3.构造函数中this是新建的对象

4.箭头函数没有自己的this,由外层作用域决定

5.通过call和apply调用的函数,它们的第一个参数就是函数的this

6.通过bind返回的函数,this由bind的第一个参数决定(无法修改)

高度塌陷

给父元素写固定高度

给外部的父盒子也添加浮动,让其也脱离标准文档流

父元素添加声明overflow:hidden;(触发一个BFC)

在元素中内容的最后添加一个伪元素,具体设置样式如下

.box:after{
	content:"";
	clear: both;
	display: block;
	height: 0;
	overflow: hidden;
	visibility: hidden;
 
}

同源策略

1.同源策略是一种约定,它是浏览器最核心也最基本的安全功能 如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。 可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。 它是一个安全策略。所有支持JavaScript的浏览器都会使用这个策略

满足同源的三个条件: 所谓同源是指,域名、协议、端口相同。

2.为什么要同源限制? 同源策略存在的意义: 非同源下的 cookie 等隐私数据可以被随意获取 非同源下的 DOM 可以的随意操作 ajax 可以任意请求的话,用户的各种隐私肯定会泄露,对用户造成不同程度的损失

3.同源策略的限制范围? 不能获取不同源的 cookie,LocalStorage 和 indexDB 不能获取不同源的 DOM() 不能发送不同源的 ajax 请求 (可以向不同源的服务器发起请求,但是返回的数据会被浏览器拦截)

git基础命令

GitHub Flow 是一个轻量级,基于分支的工作流,支持团队和项目的定期部署

	1、 git init 把这个目录变成git可以管理的仓库
	2、 git add 不但可以跟单一文件,也可以跟通配符,更可以跟目录。一个点就把当前目录下所有未追踪的文件全部add了
	3、 git commit -m ‘first commit’把文件提交到仓库
	4、 git remote add origin +//仓库地址 //关联远程仓库 
	5、 git push -u origin master //把本地库的所有内容推送到远程库上

js那些操作会造成内存泄漏

全局变量

循环引用

闭包

setTimeout setInterval

Dom

console.log打印到控制台的对象

作用域作用域链

作用域就是变量的可用性的代码范围,就叫做这个变量的作用域。简单理解,就是在这个范围内,变量是可以使用的,超过这个范围,变量就无法使用,这个范围就是作用域。

作用域分为三种:全局作用域、局部作用域、块级作用域。

全局作用域 顾名思义,全局作用域就是能够在全局使用,可以在代码的任何地方被调用

局部作用域 局部作用域只能作用于局部的代码片段,常见于函数内部,即函数内创建的变量,只能作用于函数内部,函数外部无法使用函数内部创建的变量。

块级作用域 块级作用域是es6新增的,使用let关键字创建变量、const关键字创建常量(当然let、const也会有自己的语法规范,这里不过多展开),作用域只存在于{}花括号内

什么是作用域链

当你要访问一个变量时,首先会在当前作用域下查找,如果当前作用域下没有查找到,则返回上一级作用域进行查找,直到找到全局作用域,这个查找过程形成的链条叫做作用域链。

函数柯里化

一. 什么是函数柯里化

函数柯里化是指将使用多个参数的函数转化成一系列使用一个参数的函数的技术, 它返回一个新的函数, 这个新函数去处理剩余的参数

二. 函数柯里化的实现

实现思路: 通过函数的 length 属性获取函数的形参个数, 形参的个数就是所需参数的个数

三. 函数柯里化的作用

参数复用: 本质上来说就是降低通用性, 提高适用性

假如一个函数需要两个参数, 其中一个参数可能多次调用并不会发生更改, 比如商品打折的力度, 此时可以根据折 扣进行封装

提前返回

经典实例: 元素绑定事件监听器, 区分 IE 浏览器的 attachEvent 方法

延迟计算: 柯里化函数不会立即执行计算,第一次只是返回一个函数,后面的调用才会进行计算

link和@import区别

link与@import的区别:link和import的语法结构不同,是HTML标签,只能在HTML中使用,import是css样式,可以在HTML中通过