1、浅拷贝和深拷贝的区别
浅拷贝是拷贝一层,深层次的对象级别的就拷贝引用
深拷贝是拷贝多层,每一层级的数据都会拷贝出来
1.1一段话赘述OOP编程思想
把一组数据结构和处理它们的方法组成对象(object),把相同行为的对象归纳为类(class),通过类的封装(encapsulation)隐藏内部细节,通过继承(inherit)实现类的特化(specialization)与泛化(generalization),再通过多态(polymorphic)实现基于对象类型的动态分派(dynamic allocation)。
2、闭包:
(可以看看实例:https://www.cnblogs.com/heyushuo/p/9975911.html)
闭包的特点:可以读取函数内部变量,将函数内部变量的值始终保存在内存中,保护函数内的变量不被更改
用途:
使用闭包可以访问函数中的变量
可以使变量长期保存在内存中
闭包优缺点
作用:读取函数内部的函数,始终保持在内存中
优点:变量长期保持在内存中,不会清除,避免全局污染
缺点:增大内存使用,导致内存泄漏, 网页性能问题
3、如何区分冒泡与捕获
冒泡事件(false):是指子元素向父元素传递的过程
捕获事件(true):是指父元素向子元素传递的过程
4、rem em px的区别
rem css3新增的相对单位,相对于根节点html的字体大小来计算的
em:会继承父级元素的字体大小
px:像素的相对于显示器屏幕分辨率而言的
5、年轻人不讲5的
6、js的数据类型
简单数据类型:Number、String、Boolean、 undefined、object、Null
引用类型:Object Array Function
7、面向对象的特征:封装、继承、抽象、多态
8、vue的实现原理
vue是一个典型的MVVM框架,模型Model是js对象,修改它则视图VIEW自动更新。
vue实现双向数据绑定,需要三大模块:
Observer:能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者
Compile:对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定想要的更新函数
Watcher:作为链接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图。
9、vue的生命周期
beforeCreate:组件实例刚被创建
created:组件实例创建完成,属性已绑定,但是DOM还未生成
beforeMount:模板编译
mounted:挂载
beforeUpdate:
updated:更新
beforeDestroy:实例销毁前
destroyed:销毁
10、防抖 :
(实例:https://www.cnblogs.com/momo798/p/9177767.html)
在某段时间内,不管你触发了多少次回调,我都只认最后一次。
a:如果在200ms内没有再次触发滚动事件,那么就执行函数
b:如果在200ms内再次触发滚动事件,那么当前的计时取消,重新开始计时
//防抖例子
functiondebounce(fn,wait){vartimer=null;returnfunction(){varcontext=this,args=arguments;// 如果此时存在定时器的话,则取消之前的定时器重新记时if(timer){clearTimeout(timer);timer=null;}// 设置定时器,使事件间隔指定事件后执行timer=setTimeout(()=>{fn.apply(context,args);},wait);};}
节流:在某段时间内,不管你触发了多少次回调,我都只认第一次,并在计时结束时给予响应。
// 函数节流的实现;functionthrottle(fn,delay){varpreTime=Date.now();returnfunction(){varcontext=this,args=arguments,nowTime=Date.now();// 如果两次时间间隔超过了指定时间,则执行函数。if(nowTime-preTime>=delay){preTime=Date.now();returnfn.apply(context,args);}};}
11、如何理解vue中MVVM模式?
MVVM全称是Model-View-ViewModel;
vue是以数据为驱动的,一旦创建dom和数据就保持同步,每当数据发生变化时,dom也会变化。DOMListeners和DataBindings是实现双向绑定的关键。
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 来统一管理。
12、Vue组件间的参数传递
1.父组件与子组件传值
父组件传给子组件:子组件通过props方法接受数据;
子组件传给父组件:$emit方法传递参数
2.非父子组件间的数据传递,兄弟组件传值
eventBus,就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。项目比较小时,用这个比较合适。(虽然也有不少人推荐直接用VUEX,具体来说看需求咯。技术只是手段,目的达到才是王道。)
3、多级传值:provide和inject
4、其他用vuex
13、Vue的路由实现:hash模式 和 history模式
hash模式:在浏览器中符号“#”,#以及#后面的字符称之为hash,用window.location.hash读取;
特点:hash虽然在URL中,但不被包括在HTTP请求中;用来指导浏览器动作,对服务端安全无用,hash不会重加载页面。
hash 模式下,仅 hash 符号之前的内容会被包含在请求中,如http://www.xxx.com,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误。
history模式:history采用HTML5的新特性;且提供了两个新方法:pushState(),replaceState()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更。
history 模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,如http://www.xxx.com/items/id。后端如果缺少对 /items/id 的路由处理,将返回 404 错误。Vue-Router 官网里如此描述:“不过这种模式要玩好,还需要后台配置支持……所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。
14、vue路由的钩子函数
首页可以控制导航跳转,beforeEach,afterEach等,一般用于页面title的修改。一些需要登录才能调整页面的重定向功能。
beforeEach主要有3个参数to,from,next:
to:route即将进入的目标路由对象,
from:route当前导航正要离开的路由
next:function一定要调用该方法resolve这个钩子。执行效果依赖next方法的调用参数。可以控制网页的跳转。
15、vuex是什么?怎么使用?哪种功能场景使用它?
只用来读取的状态集中放在store中; 改变状态的方式是提交mutations,这是个同步的事物; 异步逻辑应该封装在action中。
在main.js引入store,注入。新建了一个目录store,….. export 。
场景有:单页应用中,组件之间的状态、音乐播放、登录状态、加入购物车
state
Vuex 使用单一状态树,即每个应用将仅仅包含一个store 实例,但单一状态树和模块化并不冲突。存放的数据状态,不可以直接修改里面的数据。
mutations
mutations定义的方法动态修改Vuex 的 store 中的状态或数据。
getters
类似vue的计算属性,主要用来过滤一些数据。
action
actions可以理解为通过将mutations里面处里数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据。view 层通过 store.dispath 来分发 action。
16、v-if 和 v-show 区别
答:v-if按照条件是否渲染,v-show是display的block或none;
17.computed和watch的区别
computed只有当页面数据变化时才会计算,当数据没有变化时,它会读取缓存。而watch每次都需要执行函数,methods也是每次都需要执行
数据变化时执行异步操作,这个时候使用watch是合适的
分别简述computed和watch的使用场景
computed:当一个属性受多个属性影响的时候就需要用到computed
最典型的例子: 购物车商品结算的时候
watch:当一条数据影响多条数据的时候就需要用watch
例子:搜索数据
18、vue的虚拟dom?
虚拟dom实例(https://www.cnblogs.com/fundebug/p/vue-virtual-dom.html)
虚拟的DOM的核心思想是:对复杂的文档DOM结构,提供一种方便的工具,进行最小化地DOM操作。
VNode是什么?虚拟 DOM是什么?
Vue在 页面上渲染的节点,及其子节点称为“虚拟节点 (Virtual Node)”,简写为“VNode”。“虚拟 DOM”是由 Vue 组件树建立起来的整个 VNode 树的称呼。
19、vue的优点是什么?
低耦合:视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
可重用性:你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。
独立开发:开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计。
可测试:界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。
20、在Vue中使用插件的步骤
采用ES6的import ... from ...语法或CommonJSd的require()方法引入插件
使用全局方法Vue.use( plugin )使用插件,可以传入一个选项对象Vue.use(MyPlugin, { someOption: true })
21、为什么避免 v-if 和 v-for 用在一起
当 Vue 处理指令时,v-for 比 v-if 具有更高的优先级,通过v-if 移动到容器元素,不会再重复遍历列表中的每个值。取而代之的是,我们只检查它一次,且不会在 v-if 为否的时候运算 v-for
21.5vue的双向数据绑定原理是什么
vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的
核心:关于VUE双向数据绑定,其核心是 Object.defineProperty()方法;
在数据渲染时使用prop渲染数据
将prop绑定到子组件自身的数据上,修改数据时修改自身数据来替代prop
watch子组件自身数据的改变,触发事件通知父组件更改绑定到prop的数据
这样做的好处是:父组件数据改变时,不会修改存储prop的子V组件数据,只是以子组件数据为媒介,完成对prop的双向修改。
21.6、vue-router有哪几种导航钩子
全局导航钩子:router.beforeEach,afterEach;
组件内的钩子:beforeRouteEnter,beforeRoutrupdate,beforeRouteLeave,
路由独享钩子:beforeEnter
21.7、vue内置的组件
component组件:有两个属性---is inline-template
渲染一个‘元组件’为动态组件,按照'is'特性的值来渲染成那个组件
2)transition组件:为组件的载入和切换提供动画效果,具有非常强的可定制性,支持16个属性和12个事件
3)transition-group:作为多个元素/组件的过渡效果
4)keep-alive:包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们
5)slot:作为组件模板之中的内容分发插槽,slot元素自身将被替换
21.8、vuex中的getters是干什么的
可以认为是 store 的计算属性。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
21.9、插槽的理解和使用:
https://www.cnblogs.com/mandy-dyf/p/11528505.html
22、网站性能优化
1.尽可能减少HTTP请求
2.使用雪碧图
3.css放在文件最上面防止白屏,闪动,js放在最下面
4.压缩js和css 去除不必要的注释 空格
5.合理使用缓存
6.使用CDN(内容分发网络)
23、什么是盒子模型
网页中的任何一个标签都相当于是一个盒子模型,而所有的盒子模型都存在五个必要的属性:width,height,padding,border,margin.
24、css的预处理器 sass/less
优点:变量,复用,嵌套,运算,继承
缺点:提高了门槛
25、DOM操作——怎样添加、移除、移动、复制、创建和查找节点。
(1)创建新节点
createDocumentFragment() //创建一个DOM片段
createElement() //创建一个具体的元素
createTextNode() //创建一个文本节点
(2)添加、移除、替换、插入
appendChild()
removeChild()
replaceChild()
insertBefore()
(3)查找
getElementsByTagName() //通过标签名称
getElementsByName() //通过元素的Name属性的值
getElementById() //通过元素Id,唯一性
26、常见的http状态码
200 - 请求成功
301 - 资源(网页等)被永久转移到其它URL
403 - 服务器理解请求客户端的请求,但是拒绝执行此请求
404 - 请求的资源(网页等)不存在
500 - 内部服务器错误
开头为1,2的没有问题
3为重定向
4为客户端错误
5为服务器错误
27、什么是同源策略
所谓同源是指,域名,协议,端口相同。
28、如何防止xss攻击
XSS防御的总体思路是:对输入(和URL参数)进行过滤,对输出进行编码。
29、es6合并对象的方法
assign()
1.作用:将多个对象{} 合并成一个独立对象。
2.使用方式: Object.assign(合并的对象,传入合并中的对象....)
let user = {name:'无敌人',age:19};
let page = {pageSize:10,currentPage:1};
let newObj = {};
Object.assign(newObj,user,page);
30、js中怎么知道一个东西是number、string、obj?
typeof运算符用于判断对象的类型,但是对于一些创建的对象,它们都会返回'object',有时我们需要判断该实例是否为某个对象的实例,那么这个时候需要用到instanceof运算符,后续记录instanceof运算符的相关用法。
实例:console.log(typeof(true)); //'boolean'
console.log(typeof '123'); //'string'
console.log(typeof 123); //'number'
console.log(typeof NaN); //'number'
31、promise(ES6)和async/await(ES7)的区别
两者都是做异步处理的;
await 使异步转为同步,目的都是为了解决异步回调产生的“回调地狱”。
32:js的作用域和作用域链
作用域:
全局作用域:
最外层函数定义的变量拥有全局作用域,即对任何内部函数来说,都是可以访问的:
局部作用域:
和全局作用域相反,局部作用域一般只在固定的代码片段内可访问到,而对于函数外部是无法访问的,最常见的例如函数内部
函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!
作用域链:
根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问。
33、for of和for in的区别
在循环对象属性的时候,使用for...in,在遍历数组的时候的时候使用for...of。
for...in循环出的是key,for...of循环出的是value
34、如何创建BFC
根标签
float的值不为none
overflow 的值不为 visible
display 的值为 inline-block、table-cell、flex、table-caption或者inline-flex
position 的值为 absolute 或 fixed
35、csrf、xss攻击防御:
1、csrf同源策略:设置cookie的domain;
document.cookie = "username=Darren;path=/;domain=.csdn.net";
2、xss过滤
36、如何实现跨域
1、jsonp:实现简单兼容好,就是只支持get,容易遭到xss攻击;
2、最流行的跨域方案:cors;
3、最简单的nginx
37、一个完整的http过程
1、域名解析;
2、发起tcp三次握手;
3、建立tcp连接后发起http请求;
4、服务器响应http请求,浏览器得到html;
5、浏览器解析html,并请求html代码中的资源;
6、浏览器对页面进行渲染呈现给用户;(解析html构建dom树,构建render,布局render,绘制render)
38、Canvas与SVG的主要区别
从图像类别区分,Canvas是基于像素的位图,而SVG却是基于矢量图形。可以简单的把两者的区别看成photoshop与illustrator的区别。
从渲染模式上来说,Canvas属于即时模式,而SVG则是保留模式,这两种模式的区别可以参见 cshao 的博文:http://www.lifelaf.com/blog/?p=354。
从结构上说,Canvas没有图层的概念,所有的修改整个画布都要重新渲染,而SVG则可以对单独的标签进行修改。
从操作对象上说,Canvas是基于HTML canvas标签,通过宿主提供的Javascript API对整个画布进行操作的,而SVG则是基于XML元素的。
从功能上讲,SVG发布日期较早,所以功能相对Canvas比较完善。
关于动画,Canvas更适合做基于位图的动画,而SVG则适合图表的展示。关于SVG和Canvas的运行场景可参考MSCN关于如何为您的网站在Canvas和SVG之间做出选择:
从搜索引擎角度分析,由于svg是有大量标签组成,所以可以通过给标签添加属性,便于爬虫搜索。
39、promise
console.log('here we go');
new Promise( resolve => {
setTimeout( () =>{
resolve('hello');
});
})
.then( value => {
console.log(value);
return new Promise( resolve => {
setTimeout( () => {
resolve('world')
})
})
})
.then( value => {
console.log(value+' world')
})
输出: here we go
输出:hello
输出:world world
40、日常工作中如何管理公共组件?
把公共组件发布到npmjs包管理官网,然后用npm install引入
41、JS的三种加载方式
正常模式
这种情况下 JS 会阻塞浏览器,浏览器必须等待 index.js 加载和执行完毕才能去做其它事情。
async(异步) 模式
async 模式下,JS 不会阻塞浏览器做任何其它的事情。它的加载是异步的,当它加载结束,JS 脚本会立即执行。
defer(延缓) 模式
efer 模式下,JS 的加载是异步的,执行是被推迟的。等整个文档解析完成、DOMContentLoaded 事件即将被触发时,被标记了 defer 的 JS 文件才会开始依次执行。
从应用的角度来说,一般当我们的脚本与 DOM 元素和其它脚本之间的依赖关系不强时,我们会选用 async;当脚本依赖于 DOM 元素和其它脚本的执行结果时,我们会选用 defer。
42、手写一个sort方法
const insertSort = (arr, start =0, end) => {
end = end || arr.length;
for(let i = start;i < end;i++) {
let e = arr[i];
let j;
for(j =i;j > start && arr[j -1] >e;j --)
arr[j] = arr[j-1];
arr[j] =e;
}
return;
}
43、能不能描述一下原型链?
JavaScript对象通过prototype指向父类对象,直到指向Object对象为止,这样就形成了一个原型指向的链条, 即原型链。
44、什么是闭包?
闭包的定义:闭包是指有权访问另外一个函数作用域中的变量的函数
45、什么是CSRF攻击?
CSRF(Cross-site request forgery), 即跨站请求伪造,指的是黑客诱导用户点击链接,打开黑客的网站,然后黑客利用用户目前的登录状态发起跨站请求。
46、回流和重绘
回流 ,也叫重排。#触发条件
简单来说,就是当我们对 DOM 结构的修改引发 DOM 几何尺寸变化的时候,会发生回流的过程。
重绘#触发条件
当 DOM 的修改导致了样式的变化,并且没有影响几何属性的时候,会导致重绘(repaint)。
46、get和post的区别
首先最直观的是语义上的区别。
而后又有这样一些具体的差别:
从缓存的角度,GET 请求会被浏览器主动缓存下来,留下历史记录,而 POST 默认不会。
从编码的角度,GET 只能进行 URL 编码,只能接收 ASCII 字符,而 POST 没有限制。
从参数的角度,GET 一般放在 URL 中,因此不安全,POST 放在请求体中,更适合传输敏感信息。
从幂等性的角度,GET是幂等的,而POST不是。(幂等表示执行相同的操作,结果也是相同的)
从TCP的角度,GET 请求会把请求报文一次性发出去,而 POST 会分为两个 TCP 数据包,首先发 header 部分,如果服务器响应 100(continue), 然后发 body 部分。(火狐浏览器除外,它的 POST 请求只发一个 TCP 包)
47、add(1)(2)
function add (a) {
function sum(b) { // 使用闭包
a = a + b; // 累加
return sum;
}
sum.toString = function() { // 重写toSting() 方法
return a;
}
return sum; // 返回一个函数
}
console.log(add(1)(3)) // 4
console.log(add(1)(3)(5))
47.5、 我们如何将其扁平化为[1, 1, 2, 1, 2, 3]这样的一维数组呢:
1.ES6的flat()
const arr = [1, [1,2], [1,2,3]] ;
arr.flat(Infinity) // [1, 1, 2, 1, 2, 3]
48、xml与json差别
JSON相对于XML来讲,数据的体积小,传递的速度更快些。
JSON与JavaScript的交互更加方便,更容易解析处理,更好的数据交互。
SON对数据的描述性比XML较差。
JSON的速度要远远快于XML。
49、Canvas 与 SVG 的比较
Canvas
依赖分辨率
不支持事件处理器
弱的文本渲染能力
能够以 .png 或 .jpg 格式保存结果图像
最适合图像密集型的游戏,其中的许多对象会被频繁重绘
SVG
不依赖分辨率
支持事件处理器
最适合带有大型渲染区域的应用程序(比如谷歌地图)
复杂度高会减慢渲染速度(任何过度使用 DOM 的应用都不快)
不适合游戏应用
50、Express 框架中对中间件的5种分类
应用级别的中间件:挂载到 app 上的中间件 app.get('URL地址', (req, res, next)=> {});
路由级别的中间件:挂载到 router 对象上的中间件 router.get('url地址', (req, res, next)=>{})
错误级别的中间件:回调函数中,有四个参数 app.use((err, req, res, next)=>{})
唯一内置的中间件:express.static()
第三方中间件:非express框架提供的,需要程序员手动安装才能使用的中间件;body-parser 解析post 表单数据
51、Promise.all和Promise.race的区别
Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
Promise.all([promise1,promise2]).then(success1,fail1)
重点:promise1和promise2都成功才会调用success1
Promise.race
Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。
Promise.race([promise1,promise2]).then(success1,fail1)
重点:promise1和promise2只要有一个成功就会调用success1
52、自适应网站与响应式网站的区别
自适应网站是使用不同设备浏览时呈现不同的网页,网页内容及版式风格或相似或完全不同,移动端和PC端属于不同的网站模板,数据库内容或相同一致,或独立不同,目的在于为了符合访客的浏览。针对一些优化人员,更习惯于做到数据库同步,使PC端的网址和内容与移动端的网址和内容一一对应。
响应式网站是使用不同的设备浏览网站时,网站样式风格、内容和网址都是完全一样的,PC端和移动端属于同一个网站模板,数据库完全一致,也非常符合搜索引擎的优化规则。
53、expires和max-age的区别
expires是一个绝对的值,如果更改本机时间可能会造成失效.
max-age是一个相对的值,从设置那一刻开始算起,即使更改时间仍旧有效
54、nextTick和set的区别
Vue.nextTick 在下次DOM更新循环结束之后执行延迟回调;
vue.set:如果我们在创建实例以后,再在实例上绑定新属性,vue是无法进行双向绑定的。
此时如果使用vue.set的话,vue就会对新属性进行双向绑定了。
作者:九章算法
链接:https://www.jianshu.com/p/a99bbf1a5281
来源:
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。