1. vue
的双向绑定原理:
vue
的双向绑定原理是通过Object.definedProperty
的getter
和setter
来对属性进行数据劫持的。
因为Object.definedProperty
最低是支持到浏览器IE9
的,所以如果想要兼容IE8
,只能去做Object.definedProperty
的兼容,那最终使用的是做的兼容,而不是Object.definedProperty
.
找了一张图片来表示响应原理。首先Object.definedProperty
会对data
的每个属性进行数据的劫持,当我们把data
属性的值改了,就会触发它的setter
,然后通知到watcher
,watcher
再更新指令所绑定的属性的值。
- 通过`Observer`对`data`做监听,并提供了订阅某个数据项变化的能力
- 把`template`编译成一段`document fragment`,然后解析其中的`Directive`,得到每一个`Directive`所依赖的数据项和`update`方法。
- 通过`Watcher`把上述`2`部分结合起来,即把`Directive`中的数据依赖通过`Watcher`订阅在对应数据的`Observer`的`Dep`上,当数据变化时,就会触发`Observer`的`Dep`上的`notify`方法通知对应的`Watcher`的`update`,进而触发`Directive`的`update`方法来更新`dom`视图,最后达到模型和视图关联起来。
2. vue
的钩子函数:
依次为:beforeCreate ==> created ==> beforeMount ==> mounted ==> beforeUpdate ==> updated ==> beforeDestroy ==> destroyed
初始化的时候只有一次,只有当数据更改的时候才会去触发update
钩子
3. vue
的method,computed,watch
的区别:
computed
是对结果进行缓存的,只要依赖的值没有变化,结果就不会变化。method
就是普通的方法。computed
减少执行的getter
减去了重复计算,节省内存。watch
是一直在监听。比如this.num + new Date()
,虽然new Date
的值一直在变,但只要this.num
没变,结果还是一样的。
4. flex
做骰子的3
点:
html:
<div class="box">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
style:
.box{
display:flex;
}
.item:nth-child(2){
align-self:center;
}
.item:nth-child(3){
align-self:right;
}
5. css
的伪类:
:first-child/:last-children //选择第一个孩子,:nth-of-type(n)
:checked/:disabled //选择checkbox已选中的
:afeter/:before //标签的伪类
:not(selecter) //非元素的其它元素
6. 三行文本垂直居中:
1.加上下一样的padding
值,达到上下居中的目的。
2.利用table
<div class="wrapper">
<div class="cell">
<p></p>
<p></p>
<p></p>
</div>
</div>
.wapper{
displaty:table;
}
.cell{
display:table-cell;
vertical-align:center;
}
3.{position:relative;top:50%;transform:translateY(-50%)}
4.通过box
:
<div class="center">
<div>
<p></p>
<p></p>
<p></p>
</div>
</div>
.center{
display:box;
box-orient:horizontal;
box-pack:center;
box-align:center;
}
5.flex
:
<div class="flex">
<div>
<p></p>
<p></p>
<p></p>
</div>
</div>
.flex{
display:flex;
align-items:center;
}
7. 跨域的方法:
浏览器为了安全机制,采用同源策略,域名,协议,端口号一致的才可以进行访问;
1,jsonp
:是通过script
标签的src
属性来实现跨域的。通过src
传过去一个函数,把数据放在函数的实参调用就可以拿到数据。由于是用src
的链接,所以jsonp
只支持get
方式。content-type:javascript
2,cors
:改变请求头信息。客户端加:Origin:地址
。服务器:Access-Control-Allow-Origin:地址
.支持IE10
以上。
3,webpack
:devServer
里配置proxy:{api:‘地址‘}
;
4,nginx
反向代理:
nginx.conf
upstream tomcatserver{
server 192.168.72.49:8081//3.找到代理服务器的ip地址进行请求
}
server{
listen 80;
server_name 8081.max.com;//1.客户端调用名
location / {
proxy_pass http://tomcatserver;//2.到代理服务器
index index.html index.html;
}
}
8. webpack
:
loader
和plugins
的区别:loader
是负责解析代码的,而且plugins
是去做优化,代码整合之类的。
new ExtractTextPlugin(‘styles.css‘)
:分隔出css
单独打包;
new webpack.optimize.CommonsChunkPlugin({
name: ‘vendor‘,
minChunks: function (module) {
// 该配置假定你引入的 vendor 存在于 node_modules 目录中
return module.context && module.context.indexOf(‘node_modules‘) !== -1;
}
})//依赖项不重复打包,分隔模块
<LazilyLoad modules={{
TodoHandler: () => importLazy(import(‘./components/TodoHandler‘)),
TodoMenuHandler: () => importLazy(import(‘./components/TodoMenuHandler‘)),
TodoMenu: () => importLazy(import(‘./components/TodoMenu‘)),
}}>//懒加载
解析es7
用到的babel
:babel-core,babel-loader,babel-preset-es2015,babel-preset-stage-2,babe-plugin-transform-runtime,babel-runtime,babel-register.
9. es6
的声明方法,es5:var,function
:
var
:会存在变量提升,如果在声明之前用到会报undefined
.let
:不存在变量提升,如果在声明之前用到会报错。暂时性死区。块级作用域。const
:声明之后就不能改变。同上,如果是对象的话,只是指向引用的地址,所以对象里面的值改变了,是没有任何反应的。function
:声明属于window.function
class
:声明一个类import
:声明一个引用过来的模块
10. 性能优化:
压缩css,js
:体积更小,加载速度更快。css
在前,js
在后:css
在前可以和dom
树一起合成render
树,js
在后不阻塞dom
渲染。
减少http
请求:http
请求需要时间。而且要等到它请求完才能执行。请求是异步的,不知道什么时候才能请求完。webpack
配置:按需加载。分离css
。分隔依赖,把相同的依赖只打包到一起,不必重复加载。
11. 异步管理:
promise
:promise
等到执行完成后返回2
种状态,resolve
代表成功,reject
代表失败。
如果有多个异步可以用promise.all([])
.async await
:async
声明一个函数返回一个promise
。await
等到promise
异步执行结束拿到的一个结果
12. angularJS
双向绑定实现原理:
脏值检测:angular
在scope
模型上设置了一个监听队列,用来监听数据变化并更新view
,每次绑定一个东西到view
上时angular
就会往$watch
队列插入一条$watch
,用来检测它监视的model
里是否有变化的东西(一个数据一个$watcher
,对象会有一个,里面的值还会有,数组中每个对象也都会有一个)。这些$watch
列表会在$digest
循环中通过一个叫做‘脏值检测’的程序解析。angular
对大部分能产生数据变动的事件进行封装(如click
,mouse-enter
,timeout
),在每次事件发生后,比如更改了scope
中的一条数据,angular
会自动调用$digest
来触发一轮$digest
循环,它会触发每个watcher
,检查scope
中的当前model
值是否和上一次计算得到的Model
值是否一样,如不同,对应的回调函数会被执行,调用该函数的结果,就是view
中的表达式内容会被更新。
如果执行了非angular
的方法,如setTimeout
需要调用$apply()
应用到angular
上,它会调用$rootScope.$digest()
。因此,一轮$digest
循环在$rootScope
开始,随后会访问到所有的children scope
中的watchers
。
$apply()
里面可以加参数,而且会触发作用域树上所有的监控。$digest()
只作用在当前作用域和它的子作用域上。
angular
服务:sevicer
对象的实例化this.xx=
。factory
返回一个对象return{a:xx}
13. 在arr=[1,2,4]
,4
之前插入3
arr.splice(2,0,3)
14. json
字符串与json
对象的转换:
在数据传输过程中,json
是以文本,即字符串的形式传递的。而js
操作的是json
对象。
转对象:str.parseJSON()
,JSON.parse(str)
,eval(‘(‘+str+‘)‘)
转字符串:obj.toJSONString()
,JSON.stringify(obj)
15. requestAnimationFrame
和setTimeout/setInterval
:
因为js
是单线程的,setTimeout/setInterval
是在定时器线程,要等主线程走完了,才会执行事件队列。如果主线程的计算执行时间过长,那么定时器就要一直等着不能执行,就导致了,动画卡,或者一下堆在一起执行重叠过快。requestAnimationFrame
不需要设置时间间隔。IE9
以下不支持。cancelAnimationFrame()
用来取消。
16. 原型链:
每一个构造函数都有自己的原型对象,用prototype
属性来表示。每个原型对象都有一个隐式的_proto_
属性指向它父级的原型对象。如:
let a= new A()
a._proto_=A.prototype
a._proto_._proto_=A.prototype._proto_=Object.prototype
a._proto_._proto_._proto_=A.prototype._proto_._proto_=Object.prototype._proto_=null
17. 闭包:
闭包简单来说就是函数套函数。我们在函数内声明的变量叫局部变量,局部变量只能在里面访问,外面是访问不到的。如果我们想访问局部变量就可以在函数的内部在写一个函数,根据作用域链的原则就可以往上找父级的变量。
闭包会导致内存泄露的问题,解决办法是用过之后把这个变量清空还原。
18. arguments
:
arguments
是一个对应于传递给函数的参数的类数组对象。它是一个类似于数组的对象,但还不是数组。arguments.length
:实参长度。arguments.callee.length
:形参长度
可以用[].slice.call(arguments)
;或Array.from(arguments)
;[...arguments]
19. get
和post
:
get
一般表示从服务器获取数据,post
是向服务器传递数据。get
的方式是url
,因为在地址栏所以长度有限,而且地址栏的内容可以看到,所以保密性较差。
而post
是放在requst body
。对长度没有限制,保密性也较好。get
一般用于搜索。post
一般用于表单提交。
20.String
+Number
:
3 + ‘3‘ = 33
undefined + 3 = NaN //undefined为NaN,
null + 3 = 3 //null为空。
‘null‘ + 3 = ‘null3‘
当有+的时候会检查是否有类型为string的,如果有就会把其它值也转化为string格式进行字符连接。如果没有string,有number,那么会把其它值转化为number类型的值执行加法运算。
21. 循环
for(vari=0,j=0;i<5,j<10;i++,j++){
}
console.log(i+j) //20
22. 给数组加一个数组去重的方法:
Array.prototype.q=function(arr){
let obj={},a=[];
for(let i=0;i<arr.length;i++;){
if(!obj[arr[i]]){
obj[arr[i]]=true;
a.push(arr[i])
}
}
return a;
}
let arr=[3,4,4,5,6,7,72,4,3];
console.log(Array.q(a));
23. 类的继承:
es6:extends
es5
:
1.构造函数绑定:
function Cat(name,color){
Animal.apply(this,arguments);
this.name=name;
this.color=color;
}
2.利用prototype
:
function Cat(name,color){
this.name=name;
this.color=color;
}
Cat.prototype=new Animal();
Cat.prototype.constructor=Cat;
3.组合继承:
function Cat(){
Animal.call(this)
}
Cat.prototype=new Animal();
4.通过空对象:
function extend(Child,Parent){
var F=function(){};
F.prototype=Parent.prototype;
Child.prototype=new F();
Child.prototype.constructor=Child;
}
function Animal(){}
Animal.prototype.species=‘动物‘;
function Cat(name){
this.name=name;
}
extend(Cat,Animal)
5.拷贝继承:
function extend2(Child,Parent){
var p=Parent.prototype;
var c=Child.prototype;
for(var i in p){ //浅拷贝
c[i]=p[i]
}
}
extend2(Cat,Animal)
24. map
和forEach
的区别:
forEach
不能breack
,也不能return
.map
循环每一个的时候就相当于在内存中新建了一个数据,比较占内存
25. 获取url
地址:
window.location.href
26. async
的好处:
最开始的异步都是用回调函数解决的,比如ajax
,setTimeout
,addEventListener
.但是如果回调函数过多就会形成回调地狱。那么promise
就是为解决这一问题的。promise
可以用链式写法等到异步有结果再进行下一步。但如果promise
写多了也会变的不直观,async
的await
等到promise
的返回。可以让代码看起来更加简洁高效。
27. 解构出a.b.c
的值:
let obj={a:{b:{c:1}}}
let {a:{b:{c}}}=obj
console.log(c) //1
28.react
的生命周期:
29. angular
与vue
的对比:
30. 计算数组中元素出现的次数:
请输入代码