个人面试总结三


1.看过哪些框架或者类库的源码,有什么收获?

看过 vue 框架源码,对 vue 有了初步的认识,包括对 Object.defineProperty、虚拟 DOM 有一定了解,
其中的收获了有,大致明白 vue 大体可以分两个部分:

1.采用 Object.defineProperty 进行数据的双向绑定;

2.采用虚拟 DOM 技术进行视图渲染;

####2.介绍 Vue 中的常用的指令

1.v-text指令:用于更新标签包含的文本,它的作用跟双大括号效果是一样的。

<div v-text="name"></div>
<!--等同于-->
<div>{{name}}</div>

2.v-html:元素的 innerHTML

作用:向指定节点中渲染包含 html 结构的内容。

与插值语法的区别
(1).v-html 会替换掉节点中所有的内容,则不会。
(2).v-html 可以识别 html 结构。

严重注意:v-html 有安全性问题!
(1).在网站上动态渲染任意 HTML 是非常危险的,容易导致 XSS 攻击。
(2).一定要在可信的内容上使用 v-html,永不要用在用户提交的内容上!

3.v-if:v-if 指令判断是否插入这个元素,相当于对元素的销毁和创建,取值为 true/false,控制元素是否需要被渲染,

4.v-show指令:指令的取值为 true/false,分别对应着显示/隐藏

:v-show 和 v-if 的区别:如果需要频繁切换显示/隐藏的可以用 v-show;如果运行后不太可能需要切换显示/隐藏的可以用 v-if;

5.v-for指令:遍历 data 中存放的数组数据,实现列表的渲染。(v-for 指令除了可以迭代数组,还可以迭代对象和整数)

6.v-on指令:可以绑定事件的监听器。用于处理自定义原生事件的,给按钮添加 click 并让使用变量的样式改变。

普通使用 v-on:事件名=”表达式||函数名”

简写方式@事件名="表达式"

7.v-bind指令:用于动态绑定 DOM 元素的属性;例如<a>标签的href属性,<img>标签的src属性等。v-bind 可以简写成":"给元素的属性赋值

语法在元素上 v-bind:属性名=”常量||变量名”

简写形式:属性名="变量名"

<div v-bind:原属性名="变量"></div >
<!--等同于-->
<div:属性名="变量"></div>

8.v-model指令:用于表单输入,实现表单控件和数据的双向绑定。只要给 input 控件添加 v-model 指令,并指定关联的数据 content,就可以轻松把用户输入的内容绑定在 content 上。

巧记:双向数据流(绑定)
页面改变影响内存(js)
内存(js)改变影响页面

补充:v-bind 和 v-model 的区别?

input v-model="name"

双向数据绑定页面对于 input 的 value 改变,能影响内存中 name 变量

内存 js 改变 name 的值,会影响页面重新渲染最新值

input :value="name"

单向数据绑定内存改变影响页面改变

v-model:其的改变影响其他

v-bind:其的改变不影响其他

v-bind 就是对属性的简单赋值,当内存中值改变,还是会触发重新渲染

9.v-once指令:只渲染一次,后面元素中的数据再更新变化,都不会重新渲染。

####3、vue 中常用的事件修饰符

1..stop:等同于 JavaScript 中的 event.stopPropagation(),防止事件冒泡

2..prevent:等同于 JavaScript 中的 event.preventDefault(),防止执行预设的行为(如果事件可取消,则取消该事件,而不停止事件的进一步传播)

3..capture:与事件冒泡的方向相反,事件捕获由外到内

4..self:只会触发自己范围内的事件,不包含子元素

5..once:只会触发一次

4.谈谈你对 MVVM 开发模式的理解

MVVM 分别是:ModelViewViewModal

该开发模式主要体现在 vue.js 中

M 层:模型

V 层:视图

VM 层:视图模型 VM 是 MVVM 思想的核心,因为 VM 是 V 和 M 的调度者。

//VM层
var vm=new Vue({
el:'#app',
data:{//M层
msg:'你好,vue.js'
}
})

//V层
<div id='app'>
<p>{{msg}}</p>
</div>

Model:代表数据模型,数据和业务逻辑都在 Model 中定义。

View:代表 UI 视图,负责数据的展示

ViewModel:负责监听 Model 中数据的改变并且控制视图的更新。

5、v-if 和 v-show 有什么区别

(1)、v-if 和 v-show 用于视图层显示和隐藏

(2)、v-if 的原理是根据判断条件来动态的进行增删 DOM 元素,v-show 是根据判断条件来动态的进行显示和隐藏元素,频繁的进行增删 DOM 操作会影响页面加载速度和性能,由此我们可以得出结论:

当您的项目程序不是很大的时候,v-if 和 v-show 都可以用来进行判断展示和隐藏(这种场景使用 v-if 只是影响不大,并不是没有影响);

当您的项目程序比较大的时候,不推荐使用 v-if 来进行判断展示和隐藏,推荐使用 v-show;

(3)、只有 v-if 能和 v-else 连用进行分支判断,v-show 是不能和 v-else 连用的,如果出现多种条件场景的情况下,可以使用 v-if 来进行判断

6.请详细说下你对 vue 生命周期的理解?

答:总共分为 8 个阶段创建前/后,载入前/后,更新前/后,销毁前/后。

创建前/后:
在 beforeCreated 阶段,vue 实例的挂载元素 el 和 ∗∗ 数据对象 ∗∗data 都为 undefined,还未初始化。

在 created 阶段,vue 实例的数据对象 data 有了,el 还没有。

载入前/后:
在 beforeMount 阶段,vue 实例的$el 和 data 都初始化了,但还是挂载之前为虚拟的 dom 节点,data.message 还未替换。

在 mounted 阶段,vue 实例挂载完成,data.message 成功渲染。

更新前/后:当 data 变化时,会触发 beforeUpdate 和 updated 方法。

销毁前/后:在执行 destroy 方法后,对 data 的改变不会再触发周期函数,说明此时 vue 实例已经解除了事件监听以及和 dom 的绑定,但是 dom 结构依然存在。

7、计算属性及和 watch 、methods 的区别

1、computed 必须 return 一个值,主要当做属性来使用,存在缓存;
另外 computed 属性,在 vue 里面用来触发 setter 和 getter 方法。setter 方法在设置值时触发,getter 方法在获取值时触发

methods 表示一个方法,是函数调用,主要书写业务逻辑;

watch 监听某些特定数据的变化,从而进行某些具体的业务逻辑操作,可以看作是 computed 和 methods 的结合体

2、watch 相比于 methods 虽然有时候显得更繁琐,但是在监听非 DOM 元素时,显示出优势

当页面内部使用了复杂的逻辑表达式,首选使用计算属性,methods 方法虽然能实现,但是会增大开销,计算属性基于缓存,具有更优性。当需要在数据变化时执行异步或者开销较大的操作时,则优先考虑 watch 属性

8.跨域问题底层

同源策略的限制,跨域问题出现在浏览器端

跨域出现的原因:(三不同)
(1)协议不同。(http 和 https)
(2)域名不同。(test 和 tests ,或者是直接请求 IP 的不同)
(3)端口号不同。(8080 和 8081)
以上三种条件都相同,就是同域,可以正常读写域内资源,有一个条件不同,请求方与响应方都属于跨域,无法进行资源访问。
这就叫做同源策略

解决方法

(跨域资源共享)cors:目前最常用的一种解决办法,通过设置后端允许跨域实现。

jsonp:由于<script></script>,<img>中的src不受同源策略的限制,利用这一点,就有了 jsonp 这种非正式传输协议,所以 jsonp 解决跨域的原理是 script 标签可以跨域请求资源,将回调函数作为参数拼接在 url 中。后端收到请求,调用该回调函数,并将数据作为参数返回去,注意设置响应头返回文档类型,应该设置成 javascript。

代理和反向代理

在响应头里添加特殊请求头 Access-Control-Allow-Origin 信息。

9.你做过哪些性能的优化

1. 减少 HTTP 请求

  1. HTML 优化:

使用语义化标签

减少 iframe

避免重定向

  1. CSS 优化:

布局代码写前面

删除空样式

不滥用浮动、字体,需要加载的网络字体根据需求添加

选择器性能优化

避免使用表达式

避免用 id 写样式

压缩代码

  1. JS 优化

压缩代码

减少重复代码

  1. 图片优化

使用 webP

图片合并,CSS sprite 技术 - 雪碧图

移动端响应式图片 - @media(max-width:320px){}

2. 减少 DOM 操作

缓存已经访问过的元素

离线更新节点,再将他们添加到树中

避免使用 js 输出页面布局

3. 使用 JSON 格式进行数据交换

4. 使用 CDN 加速

5. 使用 HTTP 缓存:添加 Expires 或者 Cache-Control 信息头

6. 使用 DNS 预解析

  1. 用 meta 信息来告知浏览器,当前页面要做 DNS 预解析:

<meta http-equiv="x-dns-prefetch-control" content="on" />

  1. 在页面 header 中使用 link 标签来强制对 DNS 预解析:

<link rel="dns-prefetch" href="http://bdimg.share.baidu.com" />

10. vue-router 路由有几种模式?说说它们的区别?

vue-router 路由有一共有两种模式,分别是 hash 模式,history 模式

hash模式

1、 url 路径会出现 # 字符

2、hash 值不包括在 HTTP 请求中,它是交由前端路由处理,所以改变 hash 值时不会刷新页面,也不会向服务器发送请求

3、hash 值的改变会触发 hashchange 事件

history模式

1、整个地址重新加载,可以保存历史记录,方便前进后退

2、使用 HTML5 API(旧浏览器不支持)和 HTTP 服务端配置,没有后台配置的话,页面刷新时会出现 404

补充:如果 vue-router 使用 history 模式,部署时要注意什么?

HTTP 服务端需要进行配置,将页面请求全部重定向到 index.html。参考官方文档

nginx 配置:

location / {
 try_files $uri $uri/ /index.html;
}

11.说一下你对同步和异步的理解

答:同步即 sync,形象的说就是代码一行行执行,前面代码和请求没有执行完,后面的代码和请求就不会被执行,

缺点:容易导致代码阻塞

优点:程序员容易理解(因为代码从上往下一行行执行,强调顺序)

异步:即 async,形象的说就是代码可以在当前程序没有执行完,也可以执行后面的代码

缺点:程序员不易理解(因为不是按顺序执行的)

优点:可以解决代码阻塞问题,提升代码执行效率和性能

异步解决方案主要有三个:

回调函数

promise(重点掌握)

generator(了解)

async 和 await(重点掌握)

12.promise 是同步还是异步的?

1.promise 本身是同步的

let oP = new Promise((res, rej) => {
  console.log(1);
});
console.log(2);

执行的结果先打印出 1 再打印出 2,如果 promise 是异步的应该先打印出 2,所以 promise 本身是同步

2.Promise 本身是同步的,他的 then 方法的回调函数和 catch 方法的回调函数是异步的

let oP = new Promise((res, rej) => {
      console.log(1);
      res(3)
    });
    oP.then((res) => {
      console.log(res);
    });
    console.log(2);

})

执行的结果 1,2,3,因为 then 是异步的,所以先打印了 2,最后再执行回调打印出 3

补充:Promise 作用是解决异步回调的问题的方案

13.本地存储方式及区别

一、cookie

cookie 算是比较早的技术,最初是为了记录 http 的状态,提高访问速度。cookie 是服务器”种植”在客户端的 key-value 形式文本文件。但同时客户端也能操作 cookie。
特点:

大小:cookie的大小限制在4k。每个域名下cookie的个数现在在20个。
在客户端请求服务器端和服务器响应时,cookie始终被携带在http请求中,即使不需要(造成流量浪费)。这也是限制cookie大小的原因。
客户端可以通过document.cookie操作cookie,并不安全。
cookie可以设置过期时间、路径、域和httpOnly等字段。如果设置了过期时间,cookie会保存在硬盘里,知道到了设定的过期时间才会失效。若未设置过期时间,在浏览器窗口关闭时,cookie就失效了。路径和域两个字段限制了cookie的作用范围。httpOnly设置为true,则js不能通过document.cookie操作cookie。

二、localStorage

它也是采用 key-value 的形式存储数据,但是它与 cookie 有很大的区别
特点:

对比着来,localStorage能保存更大的数据,标准浏览器是5Mb。
localStorage保存在客户端,不随着请求发送给服务器,避免了流量的浪费。
客户端可以通过:setItem、getItem方法访问localStorage。
并且,localStorage没有过期时间,如果不手动清除,数据就永远不会过期,一直保存在浏览器当中。
存储的信息在同一域中是共享的。
//key,value 都必须是字符串,storage 的api 只能操作字符串
//设置
window.localStorage.setItem(key, value);
//获取
window.localStorage.getItem(key);
//删除某个数据
window.localStorage.removeItem(key);
//清除所有数据
window.localStorage.clear();
//获取某个索引的key
window.localStorage.key(index);

三、sessionStorage

特点:

与localStorage不同的是,sessionStorage并不持久化,在窗口关闭那一刻,sessionStorage会被清除。
存储的信息是会话级别的,同域也是不能共享的。关闭当前标签页,sessionStorage即失效。
//存储
sessionStorage.setItem("key","value"//按key获取值
sessionStorage.getItem(key)
//按key 删除单个值
sessionStorage.removeItems(key)
//清除所有数据
sessionStorage.clear()
//获取数据的数量
sessionStorage.length
//获取全部值
sessionStorage.valueOf()
//sessionStorage也可存储Json对象:存储时,通过JSON.stringify()将对象转换为文本格式;读取时,通过JSON.parse()将文本转换回对象。
var userEntity = {
name: 'tom',
age: 22
};

// 存储值:将对象转换为Json字符串
sessionStorage.setItem('user', JSON.stringify(userEntity));

// 取值时:把获取到的Json字符串转换回对象
var userJsonStr = sessionStorage.getItem('user');
userEntity = JSON.parse(userJsonStr);
console.log(userEntity.name); // => tom

浏览器本地存储统称为 webStorage,包括了 localStorage 和 sessionStorage

四、session(附加)

上面提到了 cookie,顺带提一下 session。客户端第一次访问服务器,服务器种植一个 cookie,保存唯一的 sessionId。后面客户端再次访问,会读取此 sessionId,随即能在服务端读取到此 id 保存的会话对象。
特点:

session 是基于 cookie 的,由于 session 在客户端不可被修改,相对于 cookie 来说安全,所以可存放一些重要数据。
数据保存在服务器端,客户端通过 sessionId,读取到相对应的数据。

14.undfind 和 null 的区别

JavaScript 的最初版本是这样区分的:null 是一个表示”无”的对象(空对象指针),转为数值时为 0;undefined 是一个表示”无”的原始值,转为数值时为 NaN。

15.什么是作用域和作用域链

作用域(Scope)

1. 什么是作用域

作用域是在运行时代码中的某些特定部分中变量,函数和对象的可访问性。换句话说,作用域决定了代码区块中变量和其他资源的可见性。可能这两句话并不好理解,我们先来看个例子:

function outFun2() {
  var inVariable = "内层变量2";
}
outFun2(); //要先执行这个函数,否则根本不知道里面是啥
console.log(inVariable); // Uncaught ReferenceError: inVariable is not defined

从上面的例子可以体会到作用域的概念,变量 inVariable 在全局作用域没有声明,所以在全局作用域下取值会报错。我们可以这样理解:

1.作用域就是一个独立的地盘,让变量不会外泄、暴露出去。

2 . 作用域是分层的,内层作用域可以访问外层作用域的变量,反之则不行。

3.变量的作用域无非就是两种:全局变量和局部变量。

ES6 之前 JavaScript 没有块级作用域,只有全局作用域和函数作用域。ES6 的到来,为我们提供了‘块级作用域’,可通过新增命令 let 和 const 来体现。

2. 什么是作用域链

根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问。
如果父级也没呢?再一层一层向上寻找,直到找到全局作用域还是没找到,就宣布放弃。这种一层一层的关系,就是 作用域链 。

16.箭头函数带来的一些问题

1. this 指向问题

在普通函数中,this 指向根据其使用场景不同改变。而箭头函数中的 this 始终指向其父级作用域

箭头函数与普通函数对 this 的指向不同,ES6 定义时 this 指向谁执行的时候 this 就指向谁。

2. 箭头函数没有原型属性

var a = () => {};
console.log(a.prototype); // undefined

3.
箭头函数通过 apply 和 bind 调用,不会改变 this 指向,只会传入参数

4.
call、apply、bind 无法改变箭头函数中的 this。

17.函数柯里化

函数柯里化的定义:是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。

通过上面的定义可以看出,柯里化是一个函数返回另一个函数,这是一个典型的闭包,它封装了一部分不变的内容,然后去处理其他可变的数据

举个官网的例子:

var abc = function (a, b, c) {
  return [a, b, c];
};
var curried = _.curry(abc);
curried(1)(2)(3);
// => [1, 2, 3]
curried(1, 2)(3);
// => [1, 2, 3]
curried(1, 2, 3);
// => [1, 2, 3]

18.JS 异步编程都有哪些方案

总结起来无外乎有这几种:回调函数、事件监听、Promise、Generator、async/await,这几种 JS 的编程方式都是异步编程。回调函数方式是最早的 JS 异步编程的方式,后随着 ES 标准的发展,Promise、Generator 和 async/await 接连出现。

19.关于 Vue 和 React 区别的一些笔记

  1. 监听数据变化的实现原理不同

Vue 通过 getter/setter 以及一些函数的劫持,能精确知道数据变化。

React 默认是通过比较引用的方式(diff)进行的

  1. 数据流的不同

vue 组件与 DOM 之间可以通过 v-model 双向绑定。

React 一直不支持双向绑定,提倡的是单向数据流,称之为 onChange/setState()模式。

  1. 框架本质不同

Vue 本质是 MVVM 框架,由 MVC 发展而来;

React 是前端组件化框架,由后端组件化发展而来。

  1. Vuex 和 Redux 的区别

Redux 使用的是不可变数据,而 Vuex 的数据是可变的,因此,Redux 每次都是用新 state 替换旧 state,而 Vuex 是直接修改。


文章作者: BiLiang
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 BiLiang !
评论
  目录