年末前端面试题小结

前言

分享一下最近面试碰到的一些题目,有些题目特别基础的题目,比如箭头函数什么作用这里就不写了。

vue实现原理

最核心的方法便是通过Object.defineProperty()来实现对属性的劫持,达到监听数据变动的目的.

  1. 实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者
  2. 实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数
  3. 实现一个Watcher,作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图.
  4. mvvm入口函数,整合以上三者

defineProperty有一个缺点就是你无法绕过定义属性这一行为,es6有一个解决方法参考学习es6的proxy 和 reflect。 再分享一个Github上一个mvvm实现:vue实现原理

vuex 和 redux 差异

Vuex 其实是一个针对 Vue 特化的 Flux,主要是为了配合 Vue 本身的响应式机制。当然吸取了一些 Redux 的特点,比如单状态树和便于测试和热重载的 API,但是也选择性的放弃了一些在 Vue 的场景下并不契合的特性,比如强制的 immutability(在保证了每一次状态变化都能追踪的情况下强制的 immutability 带来的收益就很有限了)、为了同构而设计得较为繁琐的 API、必须依赖第三方库才能相对高效率地获得状态树的局部状态等等(相比之下 Vuex 直接用 Vue 本身的计算属性就可以)所以 Vue + Vuex 会更简洁,也不需要考虑性能问题,代价就是 Vuex 只能和 Vue 配合。Vue + Redux 也不是不可以,但是 Redux 作为一个泛用的实现和 Vue 的契合度肯定不如 Vuex。

作者:尤雨溪
链接:https://www.zhihu.com/question/38546875/answer/76970954
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

通过proxy实现数据劫持

   const OBSERVERS = new  Set(); //定义一个集合存放监听函数
   const observeFn = fn => OBSERVERS.add(fn);  //定义一个监听器函数
   const observeObj = obj => new Proxy(obj, {set});
   function set(target, key, value, receiver) { //劫持set
     const result = Reflect.set(target, key, value,receiver);
     OBSERVERS.forEach(observeFn => observeFn());
     return result;
  }
  
          var person = observeObj({
            name: '张三',
            age: 20
          });
  
          function print() {
            console.log(`${person.name}, ${person.age}`)
          }
          function warn() {
            alert(person.name)
          }
          observeFn(warn);
          observeFn(print);
          person.name = '李四';

react生命周期 & setState

组件挂载中执行的函数:

  1. constructor():ES6类的构造函数(为了初始化state或绑定this)
  2. getInitialState():ES5中初始化state。(现在只需要在写在1中)
  3. getDefaultProps():ES5中初始化props。在ES6中使用defaultProps()方法。(可以写在1中,通过props)
  4. componentWillMount:组件挂载前调用,只执行一次。
  5. render():渲染组件,必须实现该方法。
  6. componentDidMount: 组件挂载后调用,只执行一次

组件的props或者state改变时更新函数:

  1. componentWillReceiveProps(nextProps): 当父组件的render()方法执行后就会触发该方法。初始化时不调用。
  2. shouldComponentUpdate(nextProps,nextState):当props改变或state改变时调用,初始化时不调用,返回boolean。true表示继续执行render方法,fasle表示放弃本次渲染。
  3. render():渲染组件。

组件卸载函数:

  1. componentWillUnmount():将组件从DOM树移出,防止内存溢出。

setState() 用于安排一个组件的 state 对象的一次更新。当状态改变时,组件通过重新渲染来响应。简单说一下原理,调用函数,react内部会执行一个任务,获取当前state,执行state更新,如果一个任务还未完成,并发了很多个setstate,react会将这些set 统一成一个更新任务,执行后只会进行一次dom更新。

虚拟dom原理

利用js解析html生成虚拟dom树,大致结构如下代码,然后利用这个虚拟dom树生成一个真的dom树渲染到页面。

diff算法:在改变dom的时候,会重新构造一个dom树,用来和旧的树相比,提取差异的部分应用到真实的dom树上。

采用虚拟dom最根本的原因就是dom操作性能消耗极大,缺点就是要写一大堆构件虚拟dom的js代码。根据项目dom操作多不多,权衡利弊合理使用虚拟dom。


var element = {
  tagName: 'ul', // 节点标签名
  props: { // DOM的属性,用一个对象存储键值对
    id: 'list'
  },
  children: [ // 该节点的子节点
    {tagName: 'li', props: {class: 'item'}, children: ["Item 1"]},
    {tagName: 'li', props: {class: 'item'}, children: ["Item 2"]},
    {tagName: 'li', props: {class: 'item'}, children: ["Item 3"]},
  ]
}

上面对应的HTML写法是:

<ul id='list'>
  <li class='item'>Item 1</li>
  <li class='item'>Item 2</li>
  <li class='item'>Item 3</li>
</ul>


移动端屏幕适配 & 触碰事件

  1. 采用flexable等插件,需要了解其原理(比如动态改写meta,html的font-size,设备dpr值等)
  2. 使用css3 嗅探改变font-size ,适配不同dpr的font-size

触摸屏幕发生的事件

  • click: 类似pc的click,但连续触发有200ms左右的延迟
  • touchstart:手指触摸到屏幕会触发
  • touchmove:当手指在屏幕上移动时,会触发
  • touchend:当手指离开屏幕时,会触发
  • touchcancel:可由系统进行的触发,比如手指触摸屏幕的时候,突然alert了一下,或者系统中其他打断了touch的行为,则可以 触发该事件

express 和 koa 差异

  1. express采用es5的callback模式,而koa采用co框架实现promise回调
  2. koa只保留基本语法,抛弃了express内置route,static等中间件

webpack原理及优化

原理

  1. 初始化参数:从配置文件和 Shell 语句中读取与合并参数,得出最终的参数
  2. 开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译;
  3. 确定入口:根据配置中的 entry 找出所有的入口文件;
  4. 编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理;
  5. 完成模块编译:在经过第4步使用 Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系;
  6. 输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会;
  7. 输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。

优化

  • 利用UglifyPlugin删除引用未使用的无用代码,压缩js代码,css添加minimize参数压缩css
  • 通过commonsChunkPlugin提取公共代码
  • 通过ParallelUglifyPlugin多线程压缩js代码
  • 缩小文件范围,通过exclude ,inclue等配置路径,优化打包效率
  • 通过happypack插件多线程处理loader
  • 通过dllplugin接入动态链接库

。。。webpack优化的方法还有很多,有兴趣的可以自行查阅

gulp基本原理

gulp可以认为是grunt的升级版,运用了node的流来处理文件,大大强化了性能。通过各种 Transform Stream 来实现文件的处理,然后再进行输出。Transform Streams 是 NodeJS Stream 的一种,是可读又可写的.

babel实现

  • babel-core:babel转译器本身,提供了babel的转译API,如babel.transform等,用于对代码进行转译。像webpack的babel-loader就是调用这些API来完成转译过程的。
  • babylon:js的词法解析器
  • babel-traverse:用于对AST(抽象语法树,想了解的请自行查询编译原理)的遍历,主要给plugin用
  • babel-generator:根据AST生成代码

babel的polyfill和runtime的区别:

Babel默认只转换新的JavaScript句法(syntax),而不转换新的API,比如Set、Proxy、Reflect、Symbol、Promise等全局对象,以及一些定义在全局对象上的方法(比如Object.assign)都不会转码。

举例来说,ES6在Array对象上新增了Array.from方法。Babel就不会转码这个方法。如果想让这个方法运行,必须使用babel-polyfill,为当前环境提供一个垫片。

ssr和客户端渲染的区别

* ssr 在服务器就把数据填充到html,返回的是完整的页面,利于所搜索引擎seo
* 更快的内容到达时间,特别是网络较差的时候
* 服务端代码没有客户端那么灵活组合
* 相比客户端渲染,ssr有更高的服务器负载,成本增加。

垂直居中实现

///不知道父容器和自身高度

parentElement{
        position:relative;
    }

 childElement{
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
 }
 
 ///使用flex
 
 parentElement{
          display: flex;
          align-items: center;
    }
 


web安全

xss攻击防御

  • 对输出的html标签进行转义(htmlEncode)
  • 对用户提交的数据进行验证,限制长度,特殊字符过滤等

sql注入防御

  • 层级化数据库权限,不要使用管理员权限
  • 对用户输入的信息进行数据库查询敏感词的过滤,限制长度等

后记

差不多就到这里了。这篇文章过年前po主将会持续更新,通过面试来找自己的不足是非常高效,面试官会针对你的简历,你的所学,针对性的考察你。前端路漫漫,其修远兮,慢慢走吧。

如果觉得本文对你有所帮助,就star一下吧~大传送之术! 我的博客Github

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容

  • 文|浪浪于江湖 全目录|【我的青春在深圳】 上一章|我的青春在深圳(35) 自从开了公众号,以晴的压力也变大了,每...
    青如许阅读 512评论 6 5
  • 遇见一棵开花的树, 便站在树下沐浴芬芳。 如果画下来, 更是一份小确幸。 十月的桂花香,经久不散,当时站在树下出神...
    叮当可好阅读 220评论 0 0
  • 父亲真的老了,变得孩子般缠人,每次打电话来,总是满怀热忱地问:你什么时候回家?且不说相隔一千多公里路,半夜起来赶飞...
    如意鸿阅读 243评论 1 4