31、hasOwnProperty 和 in
hasOwnProperty 只能获取对象自身属性、in可以获得原型链上的属性
function Fn() {
this.age = 'wm'
}
Fn.prototype.sex = '女'
var obj = new Fn()
// 实例化对象会继承构造函数里的属性和方法
console.log(obj.hasOwnProperty('age')) // true
console.log(Fn.prototype.hasOwnProperty('age')) //false
console.log(obj.hasOwnProperty('sex')) // false
32、前端有哪些安全问题以及解决办法
- XSS(Cross Site Scripting, 跨站脚本攻击) XSS攻击全称跨站脚本攻击(Cross-Site Scripting),为区别CSS,在安全领域叫做XSS。攻击者通过在目标网站上注入恶意脚本并运行,获取用户的敏感信息如 Cookie、SessionID等,影响网站与用户数据安全。 例如:留言板提交页面跳转代码,恶意劫持流量 办法:
- CSRF(Cross-site request forgery, 跨站请求伪造) CSRF(Cross-site request forgery)跨站请求伪造,攻击者盗用受害人身份,以受害人的名义发送恶意请求。 其本质是重要操作的所有参数都是可以被攻击者猜测到的,攻击者只有预测出URL的所有参数与参数值,才能成功地构造一个伪造的请求;反之,攻击者将无法攻击成功。 例如:登录网站以后,同时登陆了第三方危险网站,token信息被窃取,并伪造请求。 设置同源检测
- SQL注入 通过Web应用接口注入SQL语法,破坏原有SQL结构,达到攻击行为。 如果网站存在注入漏洞,相当于将数据库直接暴露在攻击者面前 根据注入位置及方式不同分分为POST注入、GET注入、cookie注入、盲注、延时注入、搜索注入、base64注入等 对数据进行校验,敏感字符进行转义
- 暴力破解 增加密码复杂度 限制尝试次数
33、弹性盒模型
- display:flex;设置弹性布局
- flex-direction属性 决定主轴的方向(即项目的排列方向)
- flex-wrap 属性,定义子元素是否换行显示
- flex-flow是属性flex-direction和flex-wrap的简写方式,默认值为row nowrap;
- justify-content属性定义了项目在主轴上的对齐方式。
- align-items属性定义项目在交叉轴(侧轴)上如何对齐。
- align-content属性定义了多根轴线的对齐方式。对于单行子元素,该属性不起作用。
- order属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。
- flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。
- flex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。
- align-self属性定义子项,允许和其他子项以不同的方式进行排列
34、面试问题
- 项目的背景是什么;
- 当前项目的目的是什么;
- 在开发过程中,你的角色是什么;
- 在开发过程中有遇到过什么样的难题;
- 遇到这些问题,你都是如何进行解决的;
- 项目完成之后,取得了哪些成果;
35、vue2.0响应式原理
原理 vue.js 采用数据劫持结合发布-订阅模式,通过 Object.defineproperty 来劫持各个属性的 getter进行依赖收集和setter进行派发更新,在数据变动时发布消息给订阅者,触发响应的监听回调 缺点
- 基于Object.defineProperty,不具备监听数组的能力,需要重新定义数组的原型来达到响应式。
- Object.defineProperty 无法检测到对象属性的添加和删除 。
- 由于Vue会在初始化实例时对属性执行getter/setter转化,所有属性必须在data对象上存在才能让Vue将它转换为响应式。
- 深度监听需要一次性递归,对性能影响比较大。
36、vue3.0响应式原理
改进
- 基于Proxy和Reflect,可以原生监听数组,可以监听对象属性的添加和删除。
- 不需要一次性遍历data的属性,可以显著提高性能。
- 因为Proxy是ES6新增的属性,有些浏览器还不支持,只能兼容到IE11 。
- Vue3.0基于Proxy来做数据的劫持代理,可以原生支持到数组的响应式,不需要重写数组的原型,还可以直接支持新增和删除属性, 比Vue2.x的Object.defineProperty更加的清晰明了。
let data = {
name: "zhangsan",
age: 20
};
const handler = {
get: function (target, key, receive) {
// 只处理本身(非原型)的属性
const ownKeys = Reflect.ownKeys(target)
if (ownKeys.includes(key)) {
console.log('get', key) // 监听
}
const result = Reflect.get(target, key, receive)
return result
},
set: function (target, key, val, reveive) {
// 重复的数据,不处理
const oldVal = target[key]
if (val == oldVal) {
return true
}
const result = Reflect.set(target, key, val, reveive)
console.log(result)
return result
},
// 删除属性
deleteProperty: function (target, key) {
const result = Reflect.deleteProperty(target, key)
return result
}
};
data = new Proxy(data, handler);
data.name = 'lisi'
console.log(data.name)
37、MVC和MVVM
- mvc 中 Controller演变成 mvvm 中的 viewModel
- mvvm 通过数据来驱动视图层的显示而不是节点操作。
- mvc中Model和View是可以直接打交道的,造成Model层和View层之间的耦合度高。而mvvm中Model和View不直接交互,而是通过中间桥梁ViewModel来同步
- mvvm主要解决了:mvc中大量的DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验。
38、vue特点
- 入门难度低
- 虚拟dom
- 双向绑定
- 插件化
- 轻量级
- 数据结构分离
- 数据驱动
- vue2.0不支持IE8及以下 和 vue3.0不支持IE11及以下
39、vue3.0有哪些改进
- 采用了 Proxy,抛弃了object. defineProperty Vue2.x中的响应式实现正是基于defineProperty中的descriptor,对 data 中的属性做了遍历 + 递归,为每个属性设置了 getter、setter。 这也就是为什么 Vue 只能对 data 中预定义过的属性做出响应的原因,在Vue中使用下标的方式直接修改属性的值或者添加一个预先不存在的对象属性是无法做到setter监听的,这是defineProperty的局限性。对于数组添加对七种数组操作的方法进行了监听,分别是: push、pop、shift、unshift、sort、reverse、splice函数 Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。
- 虚拟dom新增了静态节点和动态节点 Vue2.x 中的虚拟dom是进行全量的对比。 Vue3.0 中新增了静态标记(PatchFlag):在与上次虚拟结点进行对比的时候,值对比带有patch flag的节点,并且可以通过flag 的信息得知当前节点要对比的具体内容化。
- 静态提升 Vue2.x : 无论元素是否参与更新,每次都会重新创建。 Vue3.0 : 对不参与更新的元素,只会被创建一次,之后会在每次渲染时候被不停的复用。
40、生命周期函数
- beforeCreate:是new Vue()之后触发的第一个钩子,在当前阶段data、methods、computed以及watch上的数据和方法都不能被访问。
- created:在实例创建完成后发生,当前阶段已经完成了数据观测,也就是可以使用数据,更改数据,在这里更改数据不会触发updated函数。可以做一些初始数据的获取,在当前阶段无法与Dom进行交互,如果非要想,可以通过vm.$nextTick来访问Dom。
- beforeMount:发生在挂载之前,在这之前template模板已导入渲染函数编译。而当前阶段虚拟Dom已经创建完成,即将开始渲染。在此时也可以对数据进行更改,不会触发updated。
- mounted:在挂载完成后发生,在当前阶段,真实的Dom挂载完毕,数据完成双向绑定,可以访问到Dom节点,使用$refs属性对Dom进行操作。
- beforeUpdate:发生在更新之前,也就是响应式数据发生更新,虚拟dom重新渲染之前被触发,你可以在当前阶段进行更改数据,不会造成重渲染。
- updated:发生在更新完成之后,当前阶段组件Dom已完成更新。要注意的是避免在此期间更改数据,因为这可能会导致无限循环的更新。
- beforeDestroy:发生在实例销毁之前,在当前阶段实例完全可以被使用,我们可以在这时进行善后收尾工作,比如清除计时器。
- destroyed:发生在实例销毁之后,这个时候只剩下了dom空壳。组件已被拆解,数据绑定被卸除,监听被移出,子实例也统统被销毁。
- activated: 包含在keep-alive中的组件在进行调用的时候,会被存放在缓存队列中,再次调用的时候通过activated函数进行更新。
- deactivated: 与activated组件相反,在调用其他tab组件时当前会调用当前组件的deactivated函数
- errorCaptured:当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。