-
说一说 HashRouter 和 HistoryRouter的区别和原理
HashRouter和 HistoryRouter的区别:
1、hash和history都是用浏览器的两种特性实现的前端路由,history是利用浏览器历史记录栈的API实现,hash是监听location对象hash值变化事件来实现。
2、hash的URL有“#”号,history没有。
3、相同的URL,history会触发添加的浏览器的历史记录栈中,而hash不会,history需要后端进行配合,如果后端不配合刷新页面会出现404,而hash不需要。
原理:
HashRouter的原理:通过window.onhashchange方法获取新url中的值,再做进一步处理
HistoryRouter的原理:通过`history.pushState `使用它做页面跳转不会触发页面刷新,使用window.onpopstate 监听浏览器的前进和后退,再做其他处理
-
说一说对Vuex的理解;
Vuex是集中管理项目公共数据的。
Vuex 有state、mutations 、getters、actions、module属性。
state 属性用来存储公共管理的数据。
mutations 属性定义改变state中数据的方法。(注意:不要在mutation中的方法中写异步方法ajax,那样数据就不可跟踪了)
getters 属性可以认为是定义 store 的计算属性。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
action属性类似于 mutation,不同在于:Action 提交的是 mutation,而不是直接变更状态。Action 可以包含任意异步操作。
moudle属性是将store分割成模块。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块,从上至下进行同样方式的分割
-
说一说js继承的方法和优缺点
原型链继承:
让一个构造函数的原型是另一个类型的实例,那么这个构造函数new出来的实例就具有该实例的属性
优点:写法方便简洁,容易理解。
缺点:在父类型构造函数中定义的引用类型值的实例属性,会在子类型原型上变成原型属性被所有子类型实例所共享。同时在创建子类型的实例时,不能向超类型的构造函数中传递参数。
借用构造函数继承:
在子类型构造函数的内部调用父类型构造函数;使用 apply() 或 call() 方法将父对象的构造函数绑定在子对象上。
优点:解决了原型链实现继承的不能传参的问题和父类的原型共享的问题。
缺点:方法都在构造函数中定义,无法实现函数复用。在父类型的原型中定义的方法,对子类型而言也是不可见的,结果所有类型都只能使用构造函数模式。
组合继承:
原型链继承和借用构造函数继承的结合体。使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。这样,既通过在原型上定义方法实现了函数复用,又能够保证每个实例都有自己的属性。
优点:解决了原型链继承和借用构造函数继承造成的影响。
缺点:无论在什么情况下,都会调用两次超类型构造函数:一次是在创建子类型原型的时候,另一次是在子类型构造函数内部。
原型式继承:
在一个函数A内部创建一个临时性的构造函数,然后将传入的对象作为这个构造函数的原型,最后返回这个临时类型的一个新实例。本质上,函数A是对传入的对象执行了一次浅复制。
优点:不需要单独创建构造函数。
缺点:属性中包含的引用值始终会在相关对象间共享。
寄生式继承:
寄生式继承背后的思路类似于寄生构造函数和工厂模式:创建一个实现继承的函数,以某种方式增强对象,然后返回这个对象。
优点:写法简单,不需要单独创建构造函数。
缺点:通过寄生式继承给对象添加函数会导致函数难以重用。
寄生组合式继承:
通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。本质上,就是使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型。
优点:高效率只调用一次父构造函数,并且因此避免了在子原型上面创建不必要,多余的属性。与此同时,原型链还能保持不变。
缺点:代码复杂。
js new一个对象的过程
1. 创建一个空的简单JavaScript对象
2. 为新创建的对象添加属性`__proto__`,将新对象原型指向构造函数原型;
3.执行构造函数,绑定 this
4.返回新对象
function myNew(fn, ...arg) {
// 1. 创建一个空的简单JavaScript对象
let obj = {}
// 2. 为新创建的对象添加属性`__proto__`,将新对象原型指向构造函数原型;
obj._proto_ = fn.prototype
// 3.执行构造函数,绑定 this,
let res = fn.apply(obj, arg)
// 4.返回新对象
return typeof res === 'object' ? res : obj
}