某客户一的招聘需求:
1、大学本科及以上学历计算机或者计算机相关专业,三年以上互联网/移动互联网前端工作经验,精通前端开发技术(HTML5、JS、Ajax、Json、XHTML、CSS);
2、能够熟练利用HTML5、JS相关技术开发网站和客户端的前端页面,对各种浏览器的兼容性有一定了解,并有相关问题的解决经验;
3、精通主流的JS框架(zepto,jQuery),精通HTML5特性,了解HTML5最新规范,能够熟练运用HTML5特性构建移动端的WebAPP;
4、了解小程序前端设计开发,深入理解至少一种流行JS开发框架:Vue,AngularJS, React等;
5、精通Hybird研发,对H5的性能优化有深入的理解;
6、有良好的编码习惯,代码风格清晰, 简单, 保证运行效率;
7、对用户体验、交互操作流程、及用户需求有深入理解者优先;
某客户二的招聘需求:
精通HTML5 and CSS3,了解LESS或SASS;
熟悉至少一种后端开发语言, 熟练掌握API开发和调试经验者优先;
专科以上学历,4年以上工作经验;
精通HTML5、CSS3、JavaScript、jQuery等基础知识了解HTTP协议以及浏览器渲染原理;
具有构建大型面向对象的JavaScript应用程序的经验,使用过MVC模式应用程序的经验;
熟练掌握 React 、Angular 、Vue 其中一种框架和技术;
熟练掌握 ES6,typescript 等规范和技术;
汉得内面面试题一:
1、v-if和vue-show的区别?
答:v-if 是“真正的”条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
相比之下, v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
2、vue-router路由拦截?
答:全局钩子beforeEach(to,from,next)afterEach(to,from,next)
组建内的导航钩子beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave
3、vuex提供的一些方法?
答:State、Getter、Mutation、Action、Module
4、路由传参
答:直接调用$router.push 实现携带参数的跳转、通过路由属性中的name来确定匹配的路由,通过params来传递参数、使用path来匹配路由,然后通过query来传递参数
5、跨域解决方案?
答:通过jsonp跨域、nginx代{过}{滤}理跨域、nodejs中间件代{过}{滤}理跨域、WebSocket协议跨域
6、es6有哪些新属性?
答:let与const、箭头函数、字符串模版、解构、默认参数,promise等
7、js,css兼容性问题?
8、rem,px,em,vh,vh的不同?
答:px是绝对尺寸单位,其值是固定的。而em和rem是字体相对尺寸单位,其值并不固定。em会继承父级元素的字体大小,而rem则是相对于html根元素确定的。
9、清除浮动的方法?
答:使用overflow属性来清除浮动.ovh{overflow:hidden;}、使用额外标签法在浮动的盒子之下再放一个标签,在这个标签中使用clear:both,来清除浮动对页面的影响、使用伪元素来清除浮动(after意思:后来,以后)
.clearfix:after{
content:"";//设置内容为空
height:0;//高度为0
line-height:0;//行高为0
display:block;//将文本转为块级元素
visibility:hidden;//将元素隐藏
clear:both//清除浮动
}
.clearfix{
zoom:1;为了兼容IE
}
使用双伪元素清除浮动
.clearfix:before,.clearfix:after {
content: "";
display: block;
clear: both;
}
.clearfix {
zoom: 1;
}
10、Vue的双向绑定原理?
答:Vue.js则是通过数据劫持以及结合发布者-订阅者来实现的,数据劫持是利用ES5的Object.defineProperty(obj, key, val)来劫持各个属性的的setter以及getter,在数据变动时发布消息给订阅者,从而触发相应的回调来更新视图。
11、Vue父子组件通信原理
答:父组件通过props传递给子组件,但是注意通过这种方法prop默认是单向绑定, 当父组件的属性变化时,将传导给子组件,但是反过来不会。这是为了防止子组件无意修改了父组件的状态。
子组件传递数据给父组件,通过自定义事件,使用 $on(eventName) 监听事件,使用 $emit(eventName) 触发事件
12、H5新增web前端存储方式及其区别
13、CSS3新增选择器举例
14、H5新增标签举例
16、js数组去重的方法
答:ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。
17、Vue-router 动态路由如何匹配
18、Vue下template简单介绍
19、webpack的组成
首先,我觉得webpack总得来说是一个js打包工具,它的思想是模块化思想,一切都可以成为模块,不管你是js,css,还是scss,less,还是jsx,webpack统统都能打包,它有一个入口(多页面应用还没研究,,等研究了再发上来),所有的要打包的文件,都要通过这个入口进来,然后再配置一个出口,就ok了,其中要好多配置,我在这里写了一个简单的例子,先看我的结构
hand前端面试题
一、css基础
1. 设置标签浮动后该元素的display值是多少?
答:自动变成display:block;
2. css3有哪些新属性
答:1)RGBA和透明度
background-image background-origin(content-box/padding-box/border-box) background-size background-repeat
3)word-wrap(对长的不可分割单词换行)word-wrap:break-word
4)文字阴影:text-shadow: 5px 5px 5px #FF0000;(水平阴影,垂直阴影,模糊距离,阴影颜色)
5)font-face属性:定义自己的字体
6)圆角(边框半径):border-radius 属性用于创建圆角
7)边框图片:border-image: url(border.png) 30 30 round
8)盒阴影:box-shadow: 10px 10px 5px #888888
9)媒体查询:定义两套css,当浏览器的尺寸变化时会采用不同的属性
3、Css3新增的伪类有哪些
答:p:first-of-type 选择属于其父元素的首个元素
p:last-of-type 选择属于其父元素的最后元素
p:only-of-type 选择属于其父元素唯一的元素
p:only-child 选择属于其父元素的唯一子元素
p:nth-child(2) 选择属于其父元素的第二个子元素
:enabled :disabled 表单控件的禁用状态。
:checked 单选框或复选框被选中。
4、如何实现左侧固定宽度,右侧自适应沾满剩余空间
答:左侧定宽,右侧flex:1
5、 请简述几种你所知道的水平垂直居中的方法
答:1)position 元素已知宽度 2)position transform 元素未知宽度 3)方案3:flex布局 4)方案4:table-cell布局
https://blog.csdn.net/qq_27576607/article/details/78697812
6、介绍一下Cookie、LocationStorage和SessionStorage并说一下他们三者之间的区别
7、请简述px,rem、em、vW、vh
答:px是绝对尺寸单位,其值是固定的。而em和rem是字体相对尺寸单位,其值并不固定。em会继承父级元素的字体大小,而rem则是相对于html根元素确定的。
H5新增标签举例
二、JavaScript面试题
8、 javascript有哪几种数据类型
答:undefined null string boolean number symbol(ES6)
9、你讲一下Js的深拷贝和浅拷贝的区别
答: 浅拷贝:相当于使两个数组指针指向相同的地址,任一个数组元素发生改变,影响另一个。
深拷贝:两数组指针指向不同的地址,数组元素发生改变时不会相互影响。
10、介绍一下 JavaScript 原型,原型链,它们有何特点?
答:每个对象都会在其内部初始化一个属性,就是prototype(原型),当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去prototype里找这个属性,这个prototype又会有自己的prototype, 于是就这样一直找下去,也就是我们平时所说的原型链的概念。
关系:instance.constructor.prototype = instance.__proto__ //
特点:JavaScript对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本,当我们修改原型时,与之相关的对象也会继承这一改变。 // 当我们需要一个属性时,JavaScript引擎会先看当前对象中是否有这个属性,如果没有的话,就会查找它的prototype对象是否有这个属性,如此递推下去,一致检索到Object内建对象。
11、null 和 undefined 有何区别?
答:null 表示一个对象被定义了,值为“空值”; undefined 表示不存在这个值。 // typeof undefined //"undefined" undefined :是一个表示"无"的原始值或者说表示"缺少值",就是此处应该有一个值,但是还没有定义。当尝试读取时会返回 undefined; 例如变量被声明了,但没有赋值时,就等于undefined。 // typeof null //"object" null : 是一个对象(空对象, 没有任何属性和方法); 例如作为函数的参数,表示该函数的参数不是对象; // 注意: 在验证null时,一定要使用 === ,因为 == 无法分别 null 和 undefined
12、Ajax 是什么?如何创建一个 Ajax ?
(1)创建XMLHttpRequest对象,也就是创建一个异步调用对象
(2)创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息
(3)设置响应HTTP请求状态变化的函数
(4)发送HTTP请求
(5)获取异步调用返回的数据
(6)使用JavaScript和DOM实现局部刷新
readyState是XMLHttpRequest对象的一个属性,用来标识当前XMLHttpRequest对象处于什么状态。readyState总共有5个状态值,分别为0~4,每个值代表了不同的含义
0:初始化,XMLHttpRequest对象还没有完成初始化
1:载入,XMLHttpRequest对象开始发送请求
2:载入完成,XMLHttpRequest对象的请求发送完成
3:解析,XMLHttpRequest对象开始读取服务器的响应
4:完成,XMLHttpRequest对象读取服务器响应结束
// 封装一个get请求的方法
function getJSON (url) {
return new Promise(function (resolve, reject) {
// 利用Ajax发送一个请求
var XHR = new XMLHttpRequest() // 新建一个XMLHttpRequest对象
XHR.open(‘GET’, url, true) // 创建http请求
XHR.send() // 发送请求
// 设置监听状态回调函数 等待结果
XHR.onreadystatechange = function () {
if (XHR.readyState === 4) {
if (XHR.status === 200) {
try {
var res = JSON.parse(XHR.responseText)
// 得到正确的结果修改状态并将数据传递出去
resolve(res)
} catch (e) {
reject(e)
}
} else {
// 得到错误的结果并抛出异常
reject(new Error(XHR.statusText))
}
}
}
})
}
13、DOM 操作——怎样添加、移除、移动、复制、创建和查找节点?
(1)创建新节点 createDocumentFragment() //创建一个DOM片段 createElement() //创建一个具体的元素 createTextNode() //创建一个文本节点 (2)添加、移除、替换、插入 appendChild() removeChild() replaceChild() insertBefore() //在已有的子节点前插入一个新的子节点
(3)查找 getElementsByTagName() //通过标签名称 getElementsByName() //通过元素的Name属性的值(IE容错能力较强,会得到一个数组,其中包括id等于name值的) getElementById() //通过元素Id,唯一性。
14、简述一下你所知道的JavaScript对数组和字符串操作方法
数组操作的方法有:
pop()、push()、shift()、unshift()、reverse()、sort()、concat()、slice()、splice()、indexOf()、lastIndexOf()、every()、filter()、forEach()、map()、some()、reduce()、reduceRight()
charAt()、charCodeAt()、concat()、 slice()、 substr()、 substring()、 indexOf()、 lastIndexOf()、 trim()、 toLowerCase()、 toLocaleLowerCase()、 toUpperCase()、 toLocaleUpperCase()。
说一下你所知道的数组去重的方法
方法一:
var arr = [0,2,3,4,4,0,2];
var obj = {};
var tmp = [];
for(var i = 0 ;i< arr.length;i++){
if( !obj[arr] ){
obj[arr] = 1;
tmp.push(arr);
}
}
console.log(tmp);
结果如下: [0, 2, 3, 4]
方法二:
var arr = [2,3,4,4,5,2,3,6],
arr2 = [];
for(var i = 0;i< arr.length;i++){
if(arr2.indexOf(arr) < 0){
arr2.push(arr);
}
}
console.log(arr2);
结果为:[2, 3, 4, 5, 6]
方法三:
var arr = [2,3,4,4,5,2,3,6];
var arr2 = arr.filter(function(element,index,self){
return self.indexOf(element) === index;
});
console.log(arr2);
结果为:[2, 3, 4, 5, 6]
Javascript获取数组中最大值
取出数组中最大值或最小值是开发中常见的需求,今天继续讲解如何获取javascript数组中最大和最小值。
1.排序法
首先我们给数组进行排序,可以按照从小到大的顺序来排,排序之后的数组中第一个和最后一个就是我们想要获取的最小值和最大值。
排序我们会用到数组的 sort 方法。
var arr = [12,56,25,5,82,51,22];
arr.sort(function (a, b) {
return a-b;
}); // [5,12,22,25,51,56]
var min = arr[0]; // 5
var max = arr[arr.length – 1]; // 56
2.假设法
假设当前数组中的第一个值是最大值,然后拿这个最大值和后面的项逐一比较,如果后面的某一个值比假设的值还大,说明假设错了,我们把假设的值进行替换。最后得到的结果就是我们想要的。
// 获取最大值:
var arr = [22,13,6,55,30];var max = arr[0];
for(var i = 1; i < arr.length; i++) {
var cur = arr;
cur > max ? max = cur : null
}
console.log(max); // 55
// 获取最小值:
var arr = [22,13,6,55,30];var min = arr[0];
for(var i = 1; i < arr.length; i++) {
var cur = arr;
cur < min ? min = cur : null
}
console.log(min) // 6
3. 使用 Math 中的 max/min 方法
可以使用apply来实现。apply传入的是一个数组。
var arr = [22,13,6,55,30];
var max = Math.max.apply(null, arr);var min = Math.min.apply(null, arr);
console.log(max, min) // 55,6
4. 使用ES6的扩展运算符
var arr = [22,13,6,55,30];
console.log(arr.Math(…arr)); // 55
14、如何理解闭包?
1、定义和用法:当一个函数的返回值是另外一个函数,而返回的那个函数如果调用了其父函数内部的其它变量,如果返回的这个函数在外部被执行,就产生了闭包。
2、表现形式:使函数外部能够调用函数内部定义的变量。
3、实例如下:
(1)、根据作用域链的规则,底层作用域没有声明的变量,会向上一级找,找到就返回,没找到就一直找,直到window的变量,没有就返回undefined。这里明显count 是函数内部的flag2 的那个count 。
var count=10; //全局作用域 标记为flag1
function add(){
var count=0; //函数全局作用域 标记为flag2
return function(){
count+=1; //函数的内部作用域
alert(count);
}
}
var s = add()
s();//输出1
s();//输出2
4、变量的作用域
要理解闭包,首先必须理解Javascript特殊的变量作用域。
变量的作用域分类:全局变量和局部变量。
特点:
1、函数内部可以读取函数外部的全局变量;在函数外部无法读取函数内的局部变量。
2、函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!
5、使用闭包的注意点
1)滥用闭包,会造成内存泄漏:由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2)会改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
三、ES6面试题
14、你了解或者在项目中使用过的es6的语法和方法有哪些,请简单的介绍一下
let const var
1、Promise对象是什么?
2、axios、fetch与ajax有什么区别?
6、vue-cli中http请求的统一管理。
Vue面试题
1、说出至少4种vue当中的指令和它的用法?
v-if:判断是否隐藏;v-for:数据循环出来;v-bind:class:绑定一个属性;v-model:实现双向绑定
2、v-if和v-show 区别:
使用了v-if的时候,如果值为false,那么页面将不会有这个html标签生成。
v-show则是不管值为true还是false,html元素都会存在,只是CSS中的display显示或隐藏
3、请详细说下你对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结构依然存在。
4、vue路由传值的方法以及区别?
A、query要用path来引入,接收参数都是this.$route.query.name。
B、params要用name来引入,接收参数都是this.$route.params.name。
效果
A、query类似于ajax中get传参,即在浏览器地址栏中显示参数。
B、params则类似于post,即在浏览器地址栏中不显示参数。
query要用path来引入,params要用name来引入,接收参数都是类似的,分别是this.$route.query.name和this.$route.params.name。
你在项目上使用过vuex么?vuex是什么?怎么使用?哪种功能场景使用它?
vue框架中状态管理。在main.js引入store,注入。新建了一个目录store,….. export 。场景有:单页应用中,组件之间的状态。音乐播放、登录状态、加入购物车。
5、请说下封装 vue 组件的过程?
首先,组件可以提升整个项目的开发效率。能够把页面抽象成多个相对独立的模块,解决了我们传统项目开发:效率低、难维护、复用性等问题。
然后,使用Vue.extend方法创建一个组件,然后使用Vue.component方法注册组件。子组件需要数据,可以在props中接受定义。而子组件修改好数据后,想把数据传递给父组件。可以采用emit方法。
6、对于MVVM的理解?
MVVM 是 Model-View-ViewModel 的缩写。
Model代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑。
View 代表UI 组件,它负责将数据模型转化成UI 展现出来。
ViewModel 监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步View 和 Model的对象,连接Model和View。
在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。
7、Vue组件间的参数传递
1.父组件与子组件传值
父组件传给子组件:子组件通过props方法接受数据;
子组件传给父组件:$emit方法传递参数
2.非父子组件间的数据传递,兄弟组件传值
eventBus,就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。项目比较小时,用这个比较合适。(虽然也有不少人推荐直接用VUEX,具体来说看需求咯。技术只是手段,目的达到才是王道。)
3.$route和$router的区别
答:$route是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name等路由信息参数。而$router是“路由实例”对象包括了路由的跳转方法,钩子函数等。
8.vue中 key 值的作用?
答:当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。key的作用主要是为了高效的更新虚拟DOM。
9.什么是vue的计算属性?
答:在模板中放入太多的逻辑会让模板过重且难以维护,在需要对数据进行复杂处理,且可能多次使用的情况下,尽量采取计算属性的方式。好处:①使得数据处理结构清晰;②依赖于数据,数据更新,处理结果自动更新;③计算属性内部this指向vm实例;④在template调用时,直接写计算属性名即可;⑤常用的是getter方法,获取数据,也可以使用set方法改变数据;⑥相较于methods,不管依赖的数据变不变,methods都会重新计算,但是依赖数据不变的时候computed从缓存中获取,不会重新计算。
8、Vue与Angular以及React的区别?
(版本在不断更新,以下的区别有可能不是很正确。我工作中只用到vue,对angular和react不怎么熟)
1.与AngularJS的区别
相同点:
都支持指令:内置指令和自定义指令;都支持过滤器:内置过滤器和自定义过滤器;都支持双向数据绑定;都不支持低端浏览器。
不同点:
AngularJS的学习成本高,比如增加了Dependency Injection特性,而Vue.js本身提供的API都比较简单、直观;在性能上,AngularJS依赖对数据做脏检查,所以Watcher越多越慢;Vue.js使用基于依赖追踪的观察并且使用异步队列更新,所有的数据都是独立触发的。
2.与React的区别
相同点:
React采用特殊的JSX语法,Vue.js在组件开发中也推崇编写.vue特殊文件格式,对文件内容都有一些约定,两者都需要编译后使用;中心思想相同:一切都是组件,组件实例之间可以嵌套;都提供合理的钩子函数,可以让开发者定制化地去处理需求;都不内置列数AJAX,Route等功能到核心包,而是以插件的方式加载;在组件开发中都支持mixins的特性。
不同点:
React采用的Virtual DOM会对渲染出来的结果做脏检查;Vue.js在模板中提供了指令,过滤器等,可以非常方便,快捷地操作Virtual DOM。
9、vue路由的钩子函数
首页可以控制导航跳转,beforeEach,afterEach等,一般用于页面title的修改。一些需要登录才能调整页面的重定向功能。
beforeEach主要有3个参数to,from,next:
to:route即将进入的目标路由对象,
from:route当前导航正要离开的路由
next:function一定要调用该方法resolve这个钩子。执行效果依赖next方法的调用参数。可以控制网页的跳
10、vuex是什么?怎么使用?哪种功能场景使用它?
只用来读取的状态集中放在store中; 改变状态的方式是提交mutations,这是个同步的事物; 异步逻辑应该封装在action中。
在main.js引入store,注入。新建了一个目录store,….. export 。
场景有:单页应用中,组件之间的状态、音乐播放、登录状态、加入购物车。
Vuex取值
This.$store.state.city
This.$store.commit(‘getData’)
this.$store.dispath(‘getData’)
This.$store.getters.getData
Vuex中actions和mutations的区别
Mutations的更改是同步更改,用于用户执行直接数据更改,this.$store.commit(‘名’)触发
Actions的更改是异步操作,用于需要与后端交互的数据更改,this.$store.dispath(“名”)触发
如何让css只在当前组件中起作用?
将当前组件的<style>修改为<style scoped>
<keep-alive></keep-alive>的作用是什么,如何使用?
包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染;
使用:简单页面时
缓存: <keep-alive include=”组件名”></keep-alive>
不缓存:<keep-alive exclude=”组件名”></keep-alive>
使用:复杂项目时
路由字典中定义{path:’/detail’,meta:{keepAlive:false/true}} 是否缓存
根目录中:
<keep-alive><router-view v-if=”$route.meta.keepAlive”></router-view></keep-alive>
<keep-alive><router-view v-if=” ! $route.meta.keepAlive”></router-view></keep-alive>
11、scss是什么?安装使用的步骤是?有哪几大特性?
答:css的预编译。
使用步骤:
第一步:用npm 下三个loader(sass-loader、css-loader、node-sass)
第二步:在build目录找到webpack.base.config.js,在那个extends属性中加一个拓展.scss
第三步:还是在同一个文件,配置一个module属性
第四步:然后在组件的style标签加上lang属性 ,例如:lang=”scss”
有哪几大特性:
1、可以用变量,例如($变量名称=值);
2、可以用混合器,例如()
3、可以嵌套
12、导航钩子有哪些?它们有哪些参数?
答:导航钩子有:a/全局钩子和组件内独享的钩子。b/beforeRouteEnter、afterEnter、beforeRouterUpdate、beforeRouteLeave
参数:有to(去的那个路由)、from(离开的路由)、next(一定要用这个函数才能去到下一个路由,如果不用就拦截)最常用就这几种
13、Vue的双向数据绑定原理是什么?
答:vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
具体步骤:
第一步:需要observe的数据对象进行递归遍历,包括子属性对象的属性,都加上 setter和getter
这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化
第二步:compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图
第三步:Watcher订阅者是Observer和Compile之间通信的桥梁,主要做的事情是:
1、在自身实例化时往属性订阅器(dep)里面添加自己
2、自身必须有一个update()方法
3、待属性变动dep.notice()通知时,能调用自身的update()方法,并触发Compile中绑定的回调,则功成身退。
第四步:MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。
ps:16题答案同样适合”vue data是怎么实现的?”此面试题。
谈谈垃圾回收机制方式及内存管理
回收机制方式
1、定义和用法:垃圾回收机制(GC:Garbage Collection),执行环境负责管理代码执行过程中使用的内存。
2、原理:垃圾收集器会定期(周期性)找出那些不在继续使用的变量,然后释放其内存。但是这个过程不是实时的,因为其开销比较大,所以垃圾回收器会按照固定的时间间隔周期性的执行。
3、实例如下:
function fn1() {
var obj = {name: ‘hanzichi’, age: 10};
}
function fn2() {
var obj = {name:’hanzichi’, age: 10};
return obj;
}
var a = fn1();
var b = fn2();
fn1中定义的obj为局部变量,而当调用结束后,出了fn1的环境,那么该块内存会被js引擎中的垃圾回收器自动释放;在fn2被调用的过程中,返回的对象被全局变量b所指向,所以该块内存并不会被释放。
React面试题
什么是React?React有什么特点?
- React 是 Facebook 在 2011 年开发的前端 JavaScript 库。
- 它遵循基于组件的方法,有助于构建可重用的UI组件。
- 它用于开发复杂和交互式的 Web 和移动 UI。
- 尽管它仅在 2015 年开源,但有一个很大的支持社区。
eact的主要功能如下:
- 它使用虚拟DOM 而不是真正的DOM。
- 它可以进行服务器端渲染。
- 它遵循单向数据流或数据绑定。
4. 列出React的一些主要优点。
React的一些主要优点是:
- 它提高了应用的性能
- 可以方便地在客户端和服务器端使用
- 由于 JSX,代码的可读性很好
- React 很容易与 Meteor,Angular 等其他框架集成
- 使用React,编写UI测试用例变得非常容易
7. 你了解 Virtual DOM 吗?解释一下它的工作原理。
Virtual DOM 是一个轻量级的 JavaScript 对象,它最初只是 real DOM 的副本。它是一个节点树,它将元素、它们的属性和内容作为对象及其属性。
React 的渲染函数从 React 组件中创建一个节点树。然后它响应数据模型中的变化来更新该树,该变化是由用户或系统完成的各种动作引起的。
1、什么是纯函数
简单来说,一个函数的返回结果只依赖于它的参数,并且在执行过程里面没有副作用,我们就把这个函数叫做纯函数。这么说肯定比较抽象,我们把它掰开来看:
- 函数的返回结果只依赖于它的参数。
- 函数执行过程里面没有副作用。
4、react生命周期函数
这个问题要考察的是组件的生命周期
一、初始化阶段:
getDefaultProps:获取实例的默认属性
getInitialState:获取每个实例的初始化状态
componentWillMount:组件即将被装载、渲染到页面上
render:组件在这里生成虚拟的DOM节点
componentDidMount:组件真正在被装载之后
二、运行中状态:
componentWillReceiveProps:组件将要接收到属性的时候调用
shouldComponentUpdate:组件接受到新属性或者新状态的时候(可以返回false,接收数据后不更新,阻止render调用,后面的函数不会被继续执行了)
componentWillUpdate:组件即将更新不能修改属性和状态
render:组件重新描绘
componentDidUpdate:组件已经更新
三、销毁阶段:
componentWillUnmount:组件即将销毁
了解 redux 么,说一下 redux 把
- redux 是一个应用数据流框架,主要是解决了组件间状态共享的问题,原理是集中式管理,主要有三个核心方法,action,store,reducer,工作流程是 view 调用 store 的 dispatch 接收 action 传入 store,reducer 进行 state 操作,view 通过 store 提供的 getState 获取最新的数据,flux 也是用来进行数据操作的,有四个组成部分 action,dispatch,view,store,工作流程是 view 发出一个 action,派发器接收 action,让 store 进行数据更新,更新完成以后 store 发出 change,view 接受 change 更新视图。Redux 和 Flux 很像。主要区别在于 Flux 有多个可以改变应用状态的 store,在 Flux 中 dispatcher 被用来传递数据到注册的回调事件,但是在 redux 中只能定义一个可更新状态的 store,redux 把 store 和 Dispatcher 合并,结构更加简单清晰
- 新增 state,对状态的管理更加明确,通过 redux,流程更加规范了,减少手动编码量,提高了编码效率,同时缺点时当数据更新时有时候组件不需要,但是也要重新绘制,有些影响效率。一般情况下,我们在构建多交互,多数据流的复杂项目应用时才会使用它们
Redux遵循的三个原则是什么?
- 单一事实来源:整个应用的状态存储在单个 store 中的对象/状态树里。单一状态树可以更容易地跟踪随时间的变化,并调试或检查应用程序。
- 状态是只读的:改变状态的唯一方法是去触发一个动作。动作是描述变化的普通 JS 对象。就像 state 是数据的最小表示一样,该操作是对数据更改的最小表示。
- 使用纯函数进行更改:为了指定状态树如何通过操作进行转换,你需要纯函数。纯函数是那些返回值仅取决于其参数值的函数。
45. Redux 有哪些优点?
Redux 的优点如下:
- 结果的可预测性 – 由于总是存在一个真实来源,即 store ,因此不存在如何将当前状态与动作和应用的其他部分同步的问题。
- 可维护性 – 代码变得更容易维护,具有可预测的结果和严格的结构。
- 服务器端渲染 – 你只需将服务器上创建的 store 传到客户端即可。这对初始渲染非常有用,并且可以优化应用性能,从而提供更好的用户体验。
- 开发人员工具 – 从操作到状态更改,开发人员可以实时跟踪应用中发生的所有事情。
- 社区和生态系统 – Redux 背后有一个巨大的社区,这使得它更加迷人。一个由才华横溢的人组成的大型社区为库的改进做出了贡献,并开发了各种应用。
- 易于测试 – Redux 的代码主要是小巧、纯粹和独立的功能。这使代码可测试且独立。
- 组织 – Redux 准确地说明了代码的组织方式,这使得代码在团队使用时更加一致和简单。
redux 有什么缺点
- 一个组件所需要的数据,必须由父组件传过来,而不能像 flux 中直接从 store 取。
- 当一个组件相关数据更新时,即使父组件不需要用到这个组件,父组件还是会重新 render,可能会有效率影响,或者需要写复杂的 shouldComponentUpdate 进行判断
何为高阶组件(higher order component)
声明:本站所有资源均由网友分享,如有侵权内容,请在文章下方留言,本站会立即处理。