有以下 3 个判断数组的方法,请分别介绍它们之间的区别和优劣Object.prototype.toString.call() 、 instanceof 以及 Array.isArray()
Object.prototype.toString.call()
每一个继承 Object 的对象都有 toString 方法,如果 toString 方法没有重写的
const an = ['Hello','An'];
an.toString(); // "Hello,An"Object.prototype.toString.call(an); // "[object Array]"
[] instanceof Array; // true[] instanceof Object; // true
if (!Array.isArray) {
Array.isArray = function(arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
}
}
介绍下重绘和回流(Repaint & Reflow),以及如何进行优化
1. 浏览器渲染机制
<div> <a>
<span></span>
</a>
</div>
<style>
span { color: red } div > a > span { color: red } </style>
介绍下观察者模式和订阅-发布模式的区别,各自适用于什么场景
观察者模式
var subject = { //要监听的主题对象
observers: [], //保存所有的观察者
attach(observer){ //订阅方法
this.observers.push(observer)
}
notify(){
this.observer.forEach(item=>item.update()) //派发事件
}
}
var observer = {
update(){
console.log('更新了')
}
}
subject.attach(observer)
subject.notify()
订阅发布模式
var publisher = { //发布者
publish(chanel){
chanel.publish()
}
}
var chanel = { //平台
subscribers : [], //保存所有的订阅者
publish(){
this.subscriber.forEach(item=>item.update())
}
subcribe(subcriber){
this.subcribers.push(subcriber)
}
}
var subcriber = { //订阅者
update(){
console.log('更新了')
}
subcribe(){
changel.subcribe(this)
}
}
subscribe.subscribe(pubsub)
publisher.publish(pubsub)
两种模式本质都是一样的,主要关键点都在于注册(添加到注册数组中)和触发(触发注册数组中的内容),只是订阅/发布模式对注册和触发进行了解耦。可以看到,使用订阅发布模式中发布者触发publish的时候,可以选择触发哪一些订阅者集合(因为publish参数传递了中间集合,可以定义多个chanel集合),而观察者模式则只能触发所有的被观察对象。
聊聊 Redux 和 Vuex 的设计思想
链接:https://zhuanlan.zhihu.com/p/53599723
说说浏览器和 Node 事件循环的区别
链接:www.jianshu.com/p/b221e6e36…
其中一个主要的区别在于浏览器的 event loop 和 nodejs 的 event loop 在处理
异步事件的顺序是不同的,nodejs 中有 micro event;其中 Promise 属于 micro event
该异步事件的处理顺序就和浏览器不同.nodejs V11.0 以上这两者之间的顺序就相同了
function test () {
console.log('start')
setTimeout(() => {
console.log('children2')
Promise.resolve().then(() => {
console.log('children2-1')
})
}, 0)
setTimeout(() => {
console.log('children3')
Promise.resolve().then(() => {
console.log('children3-1')}
)
}, 0)
promise.resolve().then(() => {console.log('children1')})
console.log('end')
}
test()//
以上代码在 node11以下版本的执行结果(先执行所有的宏任务,再执行微任务)
// start // end // children2 // children3 // children2-1 // children3-1 //children1//
以上代码在 node11 及浏览器的执行结果(顺序执行宏任务和微任务)
// start// end// children1// children2// children2-1// children3// children3-1
介绍模块化发展历程,可从 IIFE、AMD、CMD、CommonJS、UMD、webpack(require.ensure)、ES Module、这几个角度考虑
链接:blog.csdn.net/dadadeganhu…
链接:www.cnblogs.com/lvdabao/p/j…
IIFE:自执行函数,引入外部变量问题
script标签:加载顺序不能错
CommonJs:nodejs服务器端加载方案,同步
AMD,CMD:CommonJs的进阶,浏览器端异步加载方案,require.js,sea.js,前者加载模块时就会执行,后者使用模块式才会执行,依赖就近原则。
ES Module:ES6 import加载
UMD:混合的加载方案,集成上述。
webpack:自己的模块加载方法。
全局作用域中,用 const 和 let 声明的变量不在window 上,那到底在哪里?如何去获取?
在全局作用域中,用 let 和 const 声明的全局变量并没有在全局对象中,只是一个块级作用域(Script)中。
cookie 和 token 都存放在 header 中,为什么不会劫持 token?
浏览器发送请求的时候不会自动带上token,而cookie在浏览器发送请求的时候会被自动带上。csrf就是利用的这一特性,所以token可以防范csrf,而cookie不能。
token 是放在 jwt 里面下发给客户端的 而且不一定存储在哪里 不能通过document.cookie 直接拿到,通过 jwt+ip 的方式可以防止被劫持即使被劫持也是无效的jwt
聊聊 Vue 的双向数据绑定,Model 如何改变 View,View 又是如何改变 Model 的
请把两个数组合并“['A1', 'A2', 'B1', 'B2', 'C1', 'C2', 'D1', 'D2'] 和 ['A', 'B', 'C', 'D'],合并为 ['A1', 'A2', 'A', 'B1', 'B2', 'B', 'C1', 'C2', 'C', 'D1', 'D2', 'D']”
function concatArr(arr1,arr2){ //传入要合并的两个数组
let j = 0; //这里也可以把j放在外面,用于arr2插入后还是A,B而不是B,A的情况,这种情况下j不用每次都从0开始,优化代码
var arr = [...arr1] //要返回的数组
for(let i=0;i<arr2.length;i++){
const reg = new RegExp(arr2[i]) //创建一个正则用于模式匹配
for(;j<arr.length;j++){ // j=0也可以放这里 每次都是从头开始找
if(!reg.test(arr[j])){ //没有匹配到的时候,如A遇到B1
arr.splice(j,0,arr2[i]) //就把A插入到B1前面
break // 用于一旦找到就不再找的情况
}
}
}
return arr
}