MVVM和MVC模式
Model: 就是业务逻辑相关的数据对象,通常从数据库映射而来,我们可以说是与数据库对应得model。
View: 就是展现出来的用户界面。
基本上,绝大多数软件所做的工作无非就是从数据库存储中读出数据,展现到用户界面上,然后从用户界面接受输入,写入到数据存储里面去。
如何把model展现到view上,以及如何把数据从view写入到model里,不同的人有不同的意见。
- MVC派的看法:界面上的每个变化都是一个事件,我只需要针对每个事件写一堆代码,把用户的输入转换成model里的对象就行了,这堆代码可以叫controller。
- MVVM派的看法:给view里面的各个控件也定义一个对应得数据对象,这样,只要修改这个数据对象,view里面显示的内容就自动跟着刷新,而view里面做了任何操作,这个数据对象也跟着自动更新。 所以:
ViewModel: 就是与界面(view)对应得model。因为,数据库结构往往是不能直接跟界面控件一一对应上的,所以,需要再定义一个数据对象专门对应view上的控件。而viewModel的职责就是把model对象封装成可以显示和接受输入的界面数据对象。
至于viewModel的数据跟随着view自动刷新,并且同步到model里去,这部分代码可以写成公共的框架,不用程序员自己操心了。
简单的说,viewModel就是View和Model的连接器,View与Model通过ViewModel实现双向绑定。
实现一下「模版字符串」功能;
es6.ruanyifeng.com/#docs/strin…
实现一下 Promise.all (Promise 不用写);
var p1 = new Promise((resolve,reject)=>{
setTimeout(resolve(1), 10000)
})
var p2 = new Promise((resolve,reject)=>{
setTimeout(resolve(2), 20000)
})
var p3 = new Promise((resolve,reject)=>{
setTimeout(resolve(3), 30000)
})
var p4 = new Promise((resolve,reject)=>{
throw new Error('123')
setTimeout(resolve(4), 40000)
})
function promiseAll(arr){
return new Promise((resolve, reject)=>{
var resultArr = []
arr.forEach(p => {
p.then((value)=>{
resultArr.push(value)
if(resultArr.length === arr.length){
resolve(resultArr)
}
},(reason)=> {
reject(reason)
})
});
})
}
promiseAll([p1,p2,p3,p4]).then((value)=>{
console.log(value)
},(reason)=>{
console.log(reason)
})
怎么实现响应式布局的;
- 媒体查询
- 百分比
- rem 相对于根节点html的font-size
- vw、vh (视图viewport单位)
css flex 的各个属性值;
- 容器的6个属性
- flex-direction: row | row-reverse | column | column-reverse 定义主轴的方向
- flex-wrap : wrap | no-wrap | wrap-reverse 定义项目的换行方式
- flex-flow : 默认row nowrap 是flex-direction和flex-wrap的简写
- justify-content:flex-start | flex-end | space-between | space-around | center 定义项目在主轴对齐方式
- align-items : flex-start | flex-end | center | baseline | stretch 定义项目在交叉轴对齐方式
- align-content: flex-start | flex-end | center | space-between | space-around | stretch 定义很多根轴线的对齐方式。
- 项目的6个属性
- order : 定义项目的排序顺序。数值越小,排列越靠前,默认为0。
- flex-grow:定义项目的放大比例,默认是0,即存在剩余空间也不放大。
- flex-shrink:定义项目的缩小比例,默认为1,即如果存在项目不足,该项目将缩小。
- flex-basis:定义了项目占据的固定空间,默认auto
- flex: flex-grow、flex-shrink和flex-basis的简写,默认值是0 1 auto
- align-self:auto | flex-start | flex-end | center | baseline | stretch 定义单个项目与其他项目不一样的对齐方式,可覆盖align-items,默认为auto
css 动画 animation 各个时间值含义;
- @keyframes 为动画指定一些关键帧,关键帧包含元素在特定时间所拥有的样式。
- animation-name 规定需要绑定到选择器的keyframe名称。
- animation-duration 规定完成动画所花费的时间,以秒或毫秒计。
- animation-timing-function 规定动画的速度曲线。
- animation-delay 规定在动画开始之前的延迟。
- animation-iteration-count 规定动画应该播放的次数。
- animation-direction 规定是否应该轮流反向播放动画。
css 如何实现让一个元素旋转并横向移动,如果只用一个 css 属性;
transform:
less 与 sass 区别,技术选型时如何取舍;
ES6 symbol 如何使用以及使用场景;
原文链接:blog.csdn.net/celi_echo/a…
- 使用Symbol来作为对象属性名(key)
- Symbol类型的key是不能通过Object.keys()或者for...in来枚举的,它未被包含在对象自身的属性名集合之中。所以,利用该特性,我们可以把一些不需要对外操作和访问的属性使用Symbol来定义。
- 也是因为这样的特性,当使用JSON.stringify()将对象转化为JSON字符串的时候,Symbol属性也会被排除在输出内容之外。
- 我们可以利用这一特点来更好的设计我们的数据对象,让“对内操作”和“对外选择性输出”变得更加优雅。
- 我们如何获取以Symbol方式定义的对象属性呢?
// 1. 使用Object的API
Object.getOwnPropertySymbols(obj) //[Symbol(name)]
// 2. 使用新增的反射API
Reflect.ownKeys(obj)
- 使用Symbol来代替常量
const PENDING = Symbol();
const ONFULFILLED = Symbol();
const ONREJECTED = Symbol();
- 使用Symbol定义类的私有属性、方法
-
在JavaScript中,是没有如java等面向对象语言的访问控制关键字private的,类上面定义的属性或方法都是可公开访问的。这对我们进行API设计时造成一些困扰。
-
而有了Symbol以及模块化机制,类的私有属性和方法才变成可能,例如:
-
在文件a.js中
const PASSWORD = Symbol();
class Login {
constructor(username, password) {
this.username = username;
this[PASSWORD] = password;
}
checkPassword(pwd) {
return this[PASSWORD] === pwd
}
}
export default Login;
- 在文件b.js中
import Login from './a'
const login = new Login('admin', '123456');
login.checkPassword('123456')
由于Symbol常量PASSWORD被定义在a.js所在的模块中,外面的模块获取不到这个Symbol,也不可能再创建一个一模一样的Symbol出来(因为Symbol是唯一的),因此这个PASSWORD的Symbol只能被限制在a.js内部使用,所以使用它来定义的类属性是没有办法被模块外访问的,达到了一个私有化的效果。
ES6 Proxy 如何使用以及使用场景,说说 Reflect;
参考文章: blog.flqin.com/371.html
- proxy代理
- 使用场景1:vue3的数据劫持就是基于proxy实现的
- 使用场景2:实现一个私有变量,外部只能调用不能修改
let obj = {
a: 1,
b: 2
}
new Proxy(obj, {
})
generator 有什么应用场景;
- generator返回一个迭代器
- 部署Iterator接口 利用Generator函数,可以在任意对象上部署Iterator接口
function* iterEntries(obj){
let keys = Object.keys(obj);
for(let i=0; i<keys.length; i++){
let key = keys[i];
yield [key, obj[key]]
}
}
let myObj = { foo : 3, bar : 7}
for(let [key, value] of iterEntries(myObj)){
console.log(key, value)
}
async await 如何实现的;
- async await是generator的语法糖;
- async相当于function * ;
- await相当于yield;
- 内置迭代器
- git reset 与 revert 区别,revert 多个 mr 改如何处理;
- git 如何撤回 add 后的内容;
http2 与 http1.1 区别,了解 http3 么,说说;
http2 多路复用、服务器推送
tcp 与 udp 的区别;
- tcp和udp都是传输层的协议;
- tcp是面向连接的、可靠的传输协议
- udp是无连接、不可靠的传输协议
- udp比tcp传输速度快,适合实时性高、如视频播放、在线聊天
- tcp通过三次握手、超时重传、快重传、慢启动、分包、确认应答等机制保证传输的可靠性。