前端面试题

1.vue组件中的data为什么必须是函数

  • object是复杂数据类型,假如不是函数,data中的数据将保持在内存中的同一个地址中,其中一个组件的data发送改变时,其余组件的data数据会跟着发生改变.
  • 当data是个函数时,每个组件都有自己的作用域,每个实例相互独立,不会相互影响(只有函数的{}构成作用域,对象的{}以及

1.1先要理解简单数据类型和复杂数据类型

  • 简单(基本)数据类型:Number、String、Boolean、Undefined、Null
  • 复杂(引用)数据类型: Object(Array、Date、function)

1.2简单数据类型和复杂数据类型的区别

image

1.2.1简单数据类型

  • 声明一个变量 a 的时候, 会在栈里面开辟出一块新的内存空间, 用来存放这个变量a的数值

  • 当变量 a 储存的数值发生改变时,栈区里对应的那块内存里存的数据也会发生改变

  • 这是又声明一个变量 b,并把变量a赋值给变量 b,这是在栈区里面会开辟出一块新的空间,用来存放变量 b,变量 b 的值是变量 a 传递给他的。

  • 此时这两个变量分别对应两块内存,储存的值是相同的,当变量 a 的值发生改变时,并不会影响到变量 b 的内存空间,变量 b 不会发生改变。

var a = 10;
a = 100;
var b = a;
a = 1000;
console.log(a); // 1000
console.log(b); // 100

1.2.2复杂数据类型

  • 在声明一个对象obj1时,会在堆区中开辟一块空间,用来存放obj1的数据 => obj1 = { name: ‘zs’}
  • 但是 obj1 这个变量却是存储在栈区的,obj1 指向内存中的某一个地址,通过这个地址拿到堆区对应的数据。
  • 如果将 obj1 这个对象赋值给 obj2 时,就是把 obj1 在栈区的地址传递给 obj2
  • 此时,他们共享了堆区的同一块内存空间,如果 obj1 把对象中的一个属性修改了,obj2 的属性也会发生变化
  • 如果对 obj1 重新赋值的话,那么这个对象就会指向另一块内训空间。就不再和 obj2 共享同一块内存区域了
var obj1 = { name: 'zs'}
var obj2 = obj1
obj1 = {age: 23}
console.log(obj1) // {age: 23}
console.log(obj2) // {name: "zs"}

2.构建的vue-cli工程都用到了哪些技术?作用分别是什么?

  • 1、vue.js:vue-cli工程的核心,主要特点是 双向数据绑定 和 组件系统。
  • 2、vue-router:vue官方推荐使用的路由框架。
  • 3、vuex:专为 Vue.js 应用项目开发的状态管理器,主要用于维护vue组件间共用的一些 变量 和 方法。
  • 4、axios( 或者 fetch 、ajax ):用于发起 GET 、或 POST 等 http请求,基于 Promise 设计。
  • 5、vux等:一个专为vue设计的移动端UI组件库。
  • 6、创建一个emit.js文件,用于vue事件机制的管理。
  • 7、webpack:模块加载和vue-cli工程打包器。
  • 8、element-ui:搭配vue使用的UI框架

3、vue-cli工程常用的npm命令有哪些?

创建项目结构

vue create 项目名称
  • 下载 node_modules 资源包的命令:
npm install
  • 启动 vue-cli 开发环境的 npm命令:
npm run dev   是2.0的vue-cli
npm run serve 是3.0的vue-cli
  • vue-cli 生成 生产环境部署资源 的 npm命令(使用webpack压缩打包文件):
npm run build
  • 用于查看 vue-cli 生产环境部署资源文件大小的 npm命令:
npm run build --report

4.vue.js的两个核心是什么

1.数据驱动

2.组件系统

5.vue-cli中如何使用json数据模拟

json-server

6.配置路由没有问题,但是组件没有渲染出来有几种原因

  1. router-view 容器没写
  2. template没有一个根标签
  3. 路由未在vue实例对象上挂载

7.vue全家桶是什么

  1. Vue-cli 项目构建工具
  2. vue-router 路由
  3. vuex 状态管理
  4. axios http请求工具
  5. webpack

8.axios的请求拦截器和响应拦截器分别都做了什么事情

1.请求拦截器

  1. 一般先判断本地存储中是否有用户信息,如果有,则去设置请求头中的token,如果没有则不设置token…

2.响应拦截器

  1. 在上面中,没有token则不设置的时候,访问后台信息,会返回401的状态码,此时对状态码进行检测,如果有响应,并且响应状态码是401则跳转到登录页面,进行登录.

9.token过期前端校验还是后端校验,还是都校验,如果不通过响应状态码来校验token过期,还有什么办法来校验?

10.什么是深拷贝与浅拷贝

10.1浅拷贝

  • 对内存地址的复制,让目标对象指针和源对象指向同一片内存空间
var a = {x:1}
var b = a
console.log(b);//{x:1}
b.x = 2
console.log(b)//{x:2}
console.log(a)//{x:2}
  • 浅拷贝是一个传址,也就是把a的值赋给b的时候同时也把a的址赋给了b,当b(a)的值改变的时候,a(b)的值同时也会改变

10.2深拷贝

  • 深拷贝:深拷贝是指,拷贝对象的具体内容,二内存地址是自主分配的,拷贝结束之后俩个对象虽然存的值是一样的,但是内存地址不一样,俩个对象页互相不影响,互不干涉

11.promise

promise讲解

  • 优点

    • 可以将异步操作以同步的流程表达出来
    • 可以很好地解决回调地狱的问题(避免了层层嵌套的回调函数
    • 语法非常简洁。Promise 对象提供了简洁的API,使得控制异步操作更加容易
  • 缺点

    • 无法取消Promise,一旦新建它就会立即执行,无法中途取消
    • 如果不设置回调函数,Promise内部抛出的错误,不会反应到外部
    • 当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)

用法

  • promise.all

      Promise.all([this.issueProgress(), this.itemDetail()]).then(res => {

      }).catch(err => {
        console.log(err)
      })

   
     issueProgress() {
      const params = {
        id,
        idFlag
      }
      return new Promise(resolve => {
        issueProgress(params).then(res => {
          resolve(res.data)
        })
      })
    }, 

12.key的作用

掘金

  • 提高渲染效率

  • 如果我们给列表增加了一条数据,页面只渲染了这数据,而不用让所有的数据都更新

  • v-for默认使用就地复用策略,列表数据修改的时候,他会根据key值去判断某个值是否修改,如果修改,则重新渲染这一项,否则复用之前的元素

13.输入url的过程

掘金

  • 输入URL地址

  • 浏览器进行DNS查询,查找域名对应的IP地址 2.1 浏览器在本地hosts文件中查找有没有对应的IP地址 2.2 发出一个DNS请求到本地DNS服务器 2.3 本地服务器查询缓存中是否存在对应关系,若有则返回,没有则向DNS根服务器查询 2.4 DNS根服务器返回域名所在的域名服务器 2.5 本地DNS服务器向该域名服务器发出请求,域名服务器返回该域名的解析服务器的地址 2.6 本地DNS服务器向域名的解析服务器发出请求,收到该域名和IP地址的对应关系,保存到缓存并返回

  • 建立TCP连接,浏览器向web服务发送http请求

  • 服务器处理请求,并返回状态码和html文件

  • 浏览器判断状态码,如果是 200 那就继续解析,如果 400 或 500 的话就会报错,如果 300 的话会进行重定向发送另一个请求

  • 浏览器开始显示HTML。当浏览器获得一个html文件时,会“自上而下”加载,并在加载过程中进行解析渲染。 解析: 6.1. 浏览器会将HTML解析成一个DOM树,DOM 树的构建过程是一个深度遍历过程:当前节点的所有子节点都构建好后才会去构建当前节点的下一个兄弟节点。 6.2. 将CSS解析成 CSS Rule Tree 。 6.3. 根据DOM树和CSSOM来构造 Rendering Tree。注意:Rendering Tree 渲染树并不等同于 DOM 树,因为一些像 Header 或 display:none 的东西就没必要放在渲染树中了。 6.4.有了Render Tree,浏览器已经能知道网页中有哪些节点、各个节点的CSS定义以及他们的从属关系。下一步操作称之为Layout,顾名思义就是计算出每个节点在屏幕中的位置。 6.5.再下一步就是绘制,即遍历render树,并使用UI后端层绘制每个节点。 注意点:上述这个过程是逐步完成的,为了更好的用户体验,渲染引擎将会尽可能早的将内容呈现到屏幕上,并不会等到所有的html都解析完成之后再去构建和布局render树。它是解析完一部分内容就显示一部分内容,同时,可能还在通过网络下载其余内容。

  • 浏览器发送请求获取嵌入在HTML中的资源

14.mixin

csdn

  • 更高效的实现组件内容的复用

mixin混入对象和Vuex的区别

  • Vuex是状态共享管理,所以Vuex中的所有变量和方法都是可以读取和更改并相互影响的

  • mixin可以定义公用的变量或方法,但是mixin中的数据是不共享的,也就是每个组件中的mixin实例都是不一样的,都是单独存在的个体,不存在相互影响的

  • mixin混入对象值为函数的同名函数选项将会进行递归合并为数组,两个函数都会执行,只不过先执行mixin中的同名函数

  • mixin混入对象值为对象的同名对象将会进行替换,都优先执行组件内的同名对象,也就是组件内的同名对象将mixin混入对象的同名对象进行覆盖

15.es6方法箭头函数和构造函数区别

  • 箭头函数没有 prototype (原型),所以箭头函数本身没有this
// 箭头函数
let a = () => {};
console.log(a.prototype); // undefined

// 普通函数
function a() {};
console.log(a.prototype); // {constructor:f}
  • 箭头函数没有this
    • 箭头函数没有自己的this,箭头函数的this指向在定义(**注意:**是定义时,不是调用时)的时候继承自外层第一个普通函数的this。所以,箭头函数中 this的指向在它被定义的时候就已经确定了,之后永远不会改变
let obj = {
  a: 10,
  b: () => {
    console.log(this.a); // undefined
    console.log(this); // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
  },
  c: function() {
    console.log(this.a); // 10
    console.log(this); // {a: 10, b: ƒ, c: ƒ}
  }
}
obj.b(); 
obj.c();
  • call | apply | bind 无法改变箭头函数中this的指向
    • call | apply | bind方法可以用来动态修改函数执行时this的指向,但由于箭头函数的this定义时就已经确定且永远不会改变。所以使用这些方法永远也改变不了箭头函数this``的指向。
var id = 10;
let fun = () => {
    console.log(this.id)
};
fun();     // 10
fun.call({ id: 20 });     // 10
fun.apply({ id: 20 });    // 10
fun.bind({ id: 20 })();   // 10
  • 箭头函数不能作为构造函数使用

    • 我们先了解一下构造函数的new都做了些什么?简单来说,分为四步: ① JS内部首先会先生成一个对象; ② 再把函数中的this指向该对象; ③ 然后执行构造函数中的语句; ④ 最终返回该对象实例。

      但是!!因为箭头函数没有自己的this,它的this其实是继承了外层执行环境中的this,且this指向永远不会随在哪里调用、被谁调用而改变,所以箭头函数不能作为构造函数使用,或者说构造函数不能定义成箭头函数,否则用new调用时会报错!

let Fun = (name, age) => {
    this.name = name;
    this.age = age;
};

// 报错
let p = new Fun('dingFY', 24);
  • 箭头函数不绑定arguments,取而代之用rest参数…代替arguments对象,来访问箭头函数的参数列表
    • 箭头函数没有自己的arguments对象。在箭头函数中访问arguments实际上获得的是外层局部(函数)执行环境中的值
// 普通函数
function A(a){
  console.log(arguments);
}
A(1,2,3,4,5,8);  //  [1, 2, 3, 4, 5, 8, callee: ƒ, Symbol(Symbol.iterator): ƒ]

// 箭头函数
let B = (b)=>{
  console.log(arguments);
}
B(2,92,32,32);   // Uncaught ReferenceError: arguments is not defined

// rest参数...
let C = (...c) => {
  console.log(c);
}
C(3,82,32,11323);  // [3, 82, 32, 11323]
  • **箭头函数不能用作Generator函数,不能使用yield关键字

16.v-for和if优先级

  • v-for的优先级高于v-if

  • 如果两者同时存在,可在v-for的外层包裹template这里来进行v-if判断,如果放在一起,每v-for循环一次都需要进行v-if判断,影响性能

  • 如果v-if判断出现在v-for的内部,可以通过计算属性过滤掉那么不需要的选项

17.http和https的区别

左大人
HTTP 与 HTTPS 的区别

  • HTTP 明文传输,数据都是未加密的,安全性较差,HTTPS(SSL+HTTP) 数据传输过程是加密的,安全性较好。
  • 使用 HTTPS 协议需要到 CA(Certificate Authority,数字证书认证机构) 申请证书,一般免费证书较少,因而需要一定费用。证书颁发机构如:Symantec、Comodo、GoDaddy 和 GlobalSign 等。
  • HTTP 页面响应速度比 HTTPS 快,主要是因为 HTTP 使用 TCP 三次握手建立连接,客户端和服务器需要交换 3 个包,而 HTTPS除了 TCP 的三个包,还要加上 ssl 握手需要的 9 个包,所以一共是 12 个包。
  • http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。
    HTTPS 其实就是建构在 SSL/TLS 之上的 HTTP 协议,所以,要比较 HTTPS 比 HTTP 要更耗费服务器资源。

18.vue的生命周期

<script>
    const vm = new Vue({
      el: '#app',
      data: {
        name: 'zs'
      },
      // 1. 创建阶段
      // 访问不到data
      beforeCreate() {
        // 此时没有初始化 data  和  el
        console.log('---------beforeCreate-------');
        console.log(this.name);
        console.log(this.$el);
      },
      created() {
        // 此时data已经初始化,可以使用
        // 没有初始化 el,访问不到页面上的内容
        console.log('-------------created----------');
        console.log(this.name);
        console.log(this.$el);
      },
      // 2. 挂载阶段
      beforeMount() {
        // 初始化了 el,但是没有解析指令和差值表达式
        console.log('-------------beforeMount----------');
        console.log(this.name);
        console.log(this.$el);
      },
      mounted() {
        // 初始化了 el,并且解析了指令和差值表达式。  就可以在此阶段访问元素上的内容
        console.log('-------------mounted----------');
        console.log(this.name);
        console.log(this.$el);
      },
      // 3. 更新阶段
      beforeUpdate() {
        // data 数据变化之后,还没有把变化的数据渲染到界面上
        console.log('-------------beforeUpdate----------');
        console.log(this.name);
        console.log(this.$el.innerHTML);
      },
      updated() {
        // data 数据变化之后,把变化的数据渲染到界面上了
        console.log('-------------updated----------');
        console.log(this.name);
        console.log(this.$el.innerHTML);
      },
      // 4. 卸载阶段
      beforeDestroy() {
        console.log('-------------beforeDestroy----------');
      },
      destroyed() {
        console.log('-------------destroyed----------');
      },
    });
  </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值