记录web面经

1. npm版本号含义

例如:  2.3.1 (分别表示: 大版本,小版本, 补丁版本)

大版本号: 大版本更新,功能添加,向下不兼容。
小版本号:功能新增,向下兼容。
补丁版本号: 修复bug。

~符号含义: 会匹配最近的小版本依赖包。
^符号含义: 会匹配最新的大版本依赖包。

2. npm安装包命令中,dependencies与devDependencies实际区别是什么?

在发布npm包的时候,本身 dependencies 下的模块会作为依赖,一起被下载。
devDependencies 下面的模块就不会自动下载了。
但对于项目而言,npm install 会自动下载 devDependencies 和 dependencies 下面的模块。

3. package-lock.json的作用

作用: 锁定安装时的包的版本号及包的依赖的版本号, 以保证其他所有人人在使用 ​​npm install​​ 时下载的依赖包都是一致的。
packag.json只单纯记录本项目的依赖, 而没有记录下依赖的依赖, 并且依赖之间的版本号又没有明确固定,
导致无法保证依赖环境一致。
package-lock.json的出现就是解决上述问题, 它会详细的记录项目依赖的版本号及依赖的依赖的版本号。
既然package.json会影响package-lock.json, 那后者lock的意义在哪?
  package.json确定了项目依赖的版本, 但是没有lock住依赖的依赖的版本。
  而package-lock.json就是用来lock住项目依赖的依赖。

4. vue 中 computed和watch区别?

computed: 是计算属性,根据一个属性计算出一个值,会根据所依赖的数据动态显示新的计算结果。
计算结果会被缓存,如果数据没有发生改变则使用缓存,不会重新加载。有返回值。
用户取值时才执行!!!
默认取老值,依赖值更改时才重新取新值。
【默认不执行,当取值时会触发computed属性的get方法】

watch:
watch是用来监听数据的。主要用法是当某个数据变化后,做一些操作。
当data的数据发生变化时,就会发生一个回调,有两个参数,一个newval,一个oldval。
immediate: true表示让值立即进行watch监听。
deep: 表示对对象里面的变化进行深度监听。
不支持缓存,数据变,就会直接触发相应的操作。

5.闭包

定义: 在一个函数内创建另一个函数,创建的函数可以访问到当前函数的局部变量。

用途:1.可以读取函数内部的变量;2.可以让这些变量的值始终保持在内存中。

可以解决哪些问题:
1.不必为函数命名,避免污染全局变量;
2.维持变量,使其不被垃圾回收;
3.内部形成单独的块级作用域,通过闭包实现变量/方法的私有化。

闭包缺点:
使用不当可能造成内存泄露;【因为闭包中引用到的变量永远不会被释放,所以需要及时释放这个闭包函数】

闭包产生的内存泄露怎么办:
1.在退出函数之前,将不使用的局部变量赋值为null;
2.避免变量的循环赋值和引用;

6.箭头函数和普通函数的区别?

区别:
1.写法不一样,()=>{} / function fun(){};
2.箭头函数都是匿名函数,普通函数可匿名也可具体名;
3.箭头函数不能用于构造函数,不能使用new; 普通函数可以用于构造函数,可用来创建对象实例;
4.箭头函数中的this指向其上下文,任何方法都改变不了其指向;
普通函数中this指向调用它的对象,如果是构造函数,则this指向创建的对象实例;
5.箭头函数不绑定 arguments,普通函数都有一个arguments对象。

7.浏览器缓存:协商缓存/强缓存

为什么需要浏览器缓存?
当我们访问同一个页面时,请求资源、数据都是需要一定的耗时,如果可以将一些资源缓存下来,
那么从第二次访问开始,就可以减少加载时间,提高用户体验,也能减轻服务器的压力。

协商缓存:当客户端第二次向服务器请求相同的资源时,先向服务器发送请求"询问"该请求的文件缓存在本地与服务器相比是否更改,
如果更改,则更新文件,如果没有就从内存/硬盘中读取。
由服务器的响应头里的 last-modified 和 etag 字段决定。

协商缓存流程:1.客户端第一次向服务器请求资源,服务器返回 last-modified/etag;2.客户端缓存起来,
存在内存/硬盘;3.第二次获取相同的资源,在请求头上 if-modified-since传回服务器返回
的 last-modified,if-none-match传回etag;4.服务器匹配if-modified-since/if-none
-match与本地文件的 last-modified/etag是否一致,不一致返回200,并更新last-modified/
etag的值,如果一致返回304,客户端从缓存中读取数据。

强缓存: 当客户端第二次向服务器请求相同的资源时,不会向服务器发送请求,而是直接从内存/硬盘中间读取。
由服务器的响应头里的 cache-control 和 expires 字段决定。

强缓存流程:1.客户端第一次向服务器请求资源,服务器返回 cache-control/expires;2.客户端缓存起来,
存在内存或者硬盘中;3.第二次获取相同的资源,只有资源没有过期,直接从缓存中取。

8.路由模式hash和history区别?

vue中路由模式分为 hash 和 history 模式,如果在路由中没有指定路由模式则默认开启hash模式。

hash:
路径中从 # 开始,后面的所有路径都叫做路由的哈希值。
哈希值 不会作为路径的一部分随着http请求,发给服务器。

history:
路径直接拼接在端口号后面,后面的路径会随着http请求发给服务器。

注意一点:如果项目中使用了history模式,项目部署上线时需要后端配合,因为在使用history模式的时候路径会随着http请求发
给服务器,项目打包部署时,如果后端没做配置,页面刷新,前端路径就会被当成资源去请求服务器,资源找不到就会报错404。

9.event loop


同步模式:就是前一个任务执行完成后,再执行下一个任务,程序的执行顺序与任务的排列顺序是一致的、同步的;
异步模式: 则完全不同,每一个任务有一个或多个回调函数(callback),前一个任务结束后,
不是执行队列上的后一个任务,而是执行回调函数;后一个任务则是不等前一个任务的回调函数的执行而执行,
所以程序的执行顺序与任务的排列顺序是不一致的、异步的。

异步模式分: 宏仁务和微任务。

  1、宏任务有:
     整体代码的script(外层同步代码)、setTimeOut,setInternal,DOM监听,UI渲染或UI有关事件, ajax等。

  2、微任务有:
     promise、object.observe(对象监听)、MutationObserver(监听DOM树的变化)

10. a标签,window.open,window.location.href区别?

window.location.href 是刷新当前页面,即更新浏览器地址。

window.open 是打开一个新标签页。

a标签的href是一个链接地址,没写target属性则认为是在当前页打开这个链接,效果和window.location.href一样。

11.删除数组中的某个元素

js使用delete 或splice删除数组的某个元素。

两者区别:
delete:数组的长度不变,被删除的元素变成了undefined。
splice: 该方法改变了原始数组。

12. js变量在内存中如何存储?

js中的变量在内存中的如何存储:
基本数据类型的值直接在栈内存中存储;值与值之间是独立存在的,修改一个变量不会影响其他变量;

对象(引用数据类型)是保存到堆内存中的,每创建一个新的对象,就会在堆内存中开辟一个新的空间;
而变量保存的是对象的内存地址(对象的引用),如果两个变量保存的是同一个对象引用,当变量修改属性时,
另一个也会受到影响。


当比较两个基本数据类型的值,就是比较值;
当比较两个引用数据类型时,比较的是对象的内存地址;

13.优雅实现防抖节流

防抖:在一定时间内再次触发事件,会清空上次的事件重新开始,如果在这个时间内没有再次触发,
那么这个事件才执行。

节流: 在一定的时间同一事件只会触发一次,只有超过了这个时间才会再次触发。

使用场景:搜索框,按钮,监听滚动【任何被频繁调用都有可能需要防抖或节流优化】

防抖实现: 先开启一个定时器执行,定时任务完成后则清空,当再调用时,如果定时任务仍存在则清空原来任务,
创建新的定时任务。
function debounce(fn, time){
let timer = null;
return function(){
if(timer){
clearTimeout(timer);
}
timer = setTimeout(fn.apply(this,arguments),time)
}
}

节流实现: 先开启一个定时任务执行,定时任务完成后则清空,当再调用时,如果定时任务仍存在则不执行任何操作。
function throttle(fn, time){
let timer = null;
return function(){
if(!timer){
timer = setTimeout(function(){
timer = null;
fn.apply(this,arguments);
},time)
}
}
}

 14. vue组件通信常用方式

1. props
2. $emit / $on(已废弃)
3. $children(已废弃) / $parent
4. $attrs / $listeners(已废弃)
5. ref
6. $root
7. eventbus
8. vuex (或者其他插件)

例如:
父子组件: props/$emit/$parent/ref/$attrs
兄弟组件: $parent/$root/eventbus/vuex
跨层级关系: eventbus/vuex/ provide+inject

 15.vue中如何配置代理

vue.config.js文件中:

module.exports = {
devServer: {
proxy: {
'/api': { //匹配所有以api开头的路径地址
target: '目标代理地址',
changeOrigin: true,
pathRewrite: {
'^api': ''
}
}
...
}
}
}

16.vue中v-model理解

其实v-model是vue的一个语法糖。即利用v-model绑定数据后,既绑定了数据,又添加了一个input事件监听。
实现原理:
 1、v-bind绑定响应数据;
2、触发input事件并传递数据.

双向绑定实现原理:

   当一个Vue实例创建时,Vue会遍历data选项的属性,用 Object.defineProperty 将它们转为 getter/setter并且在内部追踪相关依赖,

   在属性被访问和修改时通知变化。每个组件实例都有相应的 watcher 程序实例,它会在组件渲染的过程中把属性记录为依赖,

   之后当依赖项的 setter 被调用时,会通知 watcher重新计算,从而致使它关联的组件得以更新.

17.nextTick理解

nextTick流程:
1.把回调函数放入callbacks等待执行;
2.将执行函数放到微任务或者宏任务中;
3.事件循环到了微任务或者宏任务,执行函数依次执行callbacks中的回调;
nextTick优先放入微任务执行,而setTimeout是宏任务,因此nextTick一般情况下总是先于setTimeout执行.

问题描述:给子组件传参数后,在子组件中调用函数查看参数,虽然页面上展示了子组件的name,但是打印出来却是空值,即给data中赋值后立马去查看数据导致的。
   为了在数据更新操作之后操作DOM,我们可以在数据变化之后立即使用Vue.nextTick(callback);这样回调函数会在DOM更新完成后被调用,就可以拿到最新的DOM元素了。

 

posted on 2022-11-28 16:17  有匪  阅读(46)  评论(0编辑  收藏  举报

导航