记录一次糟糕的面试经历

2018-11-06

记一次糟糕的面试,首先总结一下这次面试存在的两个问题...

前言

记一次糟糕的面试,首先总结一下这次面试存在的两个问题,心态不好,基础细节掌握不好,可能几乎没有什么面试经历吧。这一次面试竟然罕见的感觉无比的紧张,很少自己有过连自我介绍都磕磕巴巴的时候,这一点需要自我反思。带着这种心态,第一题就开始了,说实话最近一直都再看react导致vue还真没怎么复习过,然后当这一个问题问出来的时候其实首先脑海中还是有一点点印象的,但又不敢肯定,其实还是自己当初阅读vue文档的时候没有仔细阅读。再当时的环境下导致没答好。然后当时的心态确实一下子就感觉有点儿乱了。第二题我基本上现在都还不能把题目复原,当时已经不知道自己的思路去哪里啦。值得反思。不过还是能够知道一共问我的三个问题的知识点是什么,毕竟自己是最了解自己的。

没掌握就是没掌握,不找原因,接下来掌握就好了。因此写文档来说明一下这几个问题。

Vue数组检测问题

问题复现

在vue中循环渲染data中的一个数组

vue1.png | center | 450x417vue3.png | center | 346x228

毋庸置疑,页面上现在肯定可以看到循环渲染出的1,2,3。那么我们接下来思考一个问题。

vue2.png | center | 344x454vue4.png | center | 374x457

问题描述

当我们在mounted 的时候以下标修改items会出现什么情况?页面上输出什么?为什么会输出这样的结果以及假如我们在mounted里这样呢,页面会出现什么效果。

效果是怎样的?

首先当我们在mounted中去利用__索引去给数组赋值时__,页面还是原来的1,2,3 ,但是当我此时在控制台打印我们的数组时,会发现此时的数组里已经有我们赋值好的值,此时我们就明白我们的数据已经改掉,但并未触发更新。

然后我们再来看当我们用push方法去向数组中push一个新的值是,我们会发现页面已经更新了。

关于这个问题vue的文档已经有过说明了。当初看vue的文档还仔细记过,但在自己写的为数不多的项目里,还没使用过这种方式变更数组。常用的就是push等方法。而这些方法又刚好是vue的数组变异方法,他们会触发视图更新。因此就将这个问题忽略了,之后还是要再仔仔细细却阅读一遍官方文档。

这也就解释了为什么push之后页面变化了。

原文说明

由于 JavaScript 的限制,Vue 不能检测以下变动的数组:

  1. 当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue
  2. 当你修改数组的长度时,例如:vm.items.length = newLength

为什么vue不能检测变动的数组

首先回顾一下vue是如何实现数据的双向绑定的。

把一个普通的js对象传递给vue实力的data属性,vue将遍历data的所有的属性
使用Object.definePropety把这些属性全部转化为setter/getter

访问器属性不包含数据值,他们包含一对getter函数和setter函数(这两个函数不是必须的)。
在读取访问器属性时,会调用getter函数,这个函数负责返回有效的值;
在写入访问器属性是,会调用setter函数并传入新值,这个函数负责决定如何处理数据。

访问器属性不能直接定义,必须是用Object.defineProperty()来定义

那么但data下的访问器属性值发生了改变之后,那么就会调用set函数,这时vue就可以通过set函数来追踪变化,调用相关函数来实现对视图的更新。

每个组件实例都有相应的watcher 实例对象,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter被调用时,会通知watcher 重新计算,从而致使它关联的组件得以更新。

即在渲染的过程中就会调用对象属性的getter函数,然后getter函数通知wather对象将之声明为依赖,依赖之后,如果对象属性发生了变化,那么就会调用settter函数来通知watcherwatcher就会在重新渲染组件,以此来完成更新

收到现代JavaScript浏览器的限制,其实主要是 Object.observe()方法支持的不好,Vue不能检测到对象的添加或者删除。然而Vue在初始化实例时就对属性执行了setter/getter转化过程,所以属性必须开始就在对象上,这样才能让Vue转化它。

数组中index都可以看做是属性,当我们添加属性并赋值时,Vue并不能检测到对象中属性的添加或者删除,但是其的确是添加或删除了,故我们可以通过console看到变化,所以就没有办法做到响应式

参考文档

vue官方文档 vue中遇到的坑 --- 变化检测问题(数组相关)

Javascript继承问题

说实话这一题题目我已经复现不了了,说实话在提问的时候就完全没有跟着面试官的思路走。不过还是可以知道他主要问的我这一部分的知识点。关于这一部分,说实话深入理解没有特别深入,简单的题目回答是什么可以,但要我说出全部,还是有问题的。所以重新翻一遍高程第六章,网上查一些资料好好理解一下。

继承方式

  • 原型链继承
  • 借用构造函数继承
  • 组合继承
  • 原型式继承
  • 寄生式继承
  • 寄生组合式继承

这个知识点篇幅有点长重新写一篇了文档Js原型、原型链、this、继承的笔记

两列布局左边定宽右边自适应

关于css布局方面,一直都觉着css玩的好的也很厉害,但我还是觉着对css来说,始终要找到一个最优方案。这是我个人目前的理解。

实现方式

  • inline-block
  • float
  • float+margin-left
  • float+BFC
  • flex
  • grid
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <link rel="stylesheet" href="./style.css">
</head>
<body>
  <div class="content">
    <div class="left">我是左边</div>
    <div class="right">我是右边</div>
  </div>
</body>
</html>

inline-block方案

.left{
  width: 250px;
  background-color: black;
  color: #fff;
  height: 670px;
}

.left,
.right{
  display: inline-block;
  vertical-align: top;
  font-size: 1rem;
}

.right{
  width: calc(100% - 250px);
  
}

.content{
  font-size: 0;

float方案

.content{
  overflow: auto;
}

.left,
.right{
  float: left;
}

.right{
  width: calc(100% - 250px);
}

float+margin-left

.content{
  overflow: auto;
}

.left{
  float: left;
}

.right{
  margin-left: 250px;
}

float+BFC

.content{
  overflow: auto;
}

.left{
  float: left;
}

.right{
  overflow: auto;
} 

flex

.content{
  display: flex;
  align-items: flex-start;
}

.left{
  flex: none;
}

.right{
  flex: auto;
}

grid

.content{
  display: grid;
  grid-template-columns: 250px 1fr;
  align-items: start;
}