当属性名称与变量名称不一致的,需要显式的指定属性名。这样才能把属性值给赋值到变量中。
例如:
let user = {name: '小明', age: 12};
let {name: userName, age: userAge} = user;
console.log(userName); // '小明'
console.log(userAge); // 12
剩余运算符
let [a,...b] = [1,2,3,4,5]
console.log(a) //1
console.log(b) ///[2,3,4,5]
扩展运算符
let a = [1,2,3]
let b = [...a]
console.log(b) //[1,2,3]
剩余运算符和扩展运算符的区别就是,剩余运算符会收集这些集合,放到右边的数组中,扩展运算符是将右边的数组拆分成元素的集合,它们是相反的
ES9中支持在对象中使用扩展运算符,之前说过数组的扩展运算符原理是消耗所有迭代器,但对象中并没有迭代器,我个人认为可能是实现原理不同,但是仍可以理解为将键值对从对象中拆开,它可以放到另外一个普通对象中
es6允许当对象的属性和值相同时,省略属性名- 省略的是属性名而不是值,值必须是一个变量
es6允许当一个对象的属性的值是一个函数(即是一个方法),可以使用简写的形式
for ... of循环
for ... of是作为ES6新增的遍历方式,允许遍历一个含有iterator接口的数据结构并且返回各项的值,和ES3中的for ... in的区别如下
- for ... of只能用在可迭代对象上,获取的是迭代器返回的value值,for ... in 可以获取所有对象的键名
- for ... in会遍历对象的整个原型链,性能非常差不推荐使用,而for ... of只遍历当前对象不会遍历它的原型链
- 对于数组的遍历,for ... in会返回数组中所有可枚举的属性(包括原型链上可枚举的属性),for ... of只返回数组的下标对应的属性值
for... of循环同时支持break,continue, return(在函数中调用的话)
Promise.all([p1, p2]).then((result) => {
console.log(result) //['成功了', 'success']
}).catch((error) => {
console.log(error)
})
成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值。
Promise.race([p1, p2]).then((result) => {
console.log(result)
}).catch((error) => {
console.log(error) // 打开的是 'failed'
})
Promse.race就是赛跑的意思,意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。
require:运行时加载
import:编译时加载(效率更高)【由于是编译时加载,所以import命令会提升到整个模块的头部】
test();
import { test} from '/test';
12
上面的代码不会报错,正常执行
require引入的模块就是一个对象
import:ES6 模块不是对象,而是通过 export 命令显式指定输出的代码,再通过 import 命令输入
commonjs的exports 和 module.exports
在一个node执行一个文件时,会给这个文件内生成一个 exports和module对象,
而module又有一个exports属性。他们之间的关系如下图,都指向一块{}内存区域。
exports = module.exports = {};
//utils.js
let a = 100;
console.log(module.exports); //能打印出结果为:{}
console.log(exports); //能打印出结果为:{}
exports.a = 200; //这里辛苦劳作帮 module.exports 的内容给改成 {a : 200}
exports = '指向其他内存区'; //这里把exports的指向指走
//test.js
var a = require('/utils');
console.log(a) // 打印为 {a : 200}
从上面可以看出,其实
require导出的内容是module.exports的指向的内存块内容,并不是exports的。
简而言之,区分他们之间的区别就是exports只是module.exports的引用,辅助后者添加内容用的。
用白话讲就是,exports只辅助module.exports操作内存中的数据,最后真正被require出去的内容还是module.exports的。
export 和 export default
- export与export default均可用于导出常量、函数、文件、模块等
- 在一个文件或模块中,export、import可以有多个,export default仅有一个
- 通过export方式导出,在导入时要加{ },export default则不需要
- export能直接导出变量表达式,export default不行。
export {<变量>}导出的是一个变量的引用,export default导出的是一个值的拷贝
- CommonJs在第一次加载的时候运行一次并且会生成一个缓存,之后加载返回的都是缓存中的内容
关于ES6 Module静态编译的特点,导致了无法动态加载,但是总是会有一些需要动态加载模块的需求,所以现在有一个提案,使用把import作为一个函数可以实现动态加载模块,它返回一个Promise,Promise被resolve时的值为输出的模块
Vue中路由的懒加载的ES6写法就是使用了这个技术,使得在路由切换的时候能够动态的加载组件渲染视图
- View 传送指令到 Controller
- Controller 完成业务逻辑后,要求 Model 改变状态
- Model 将新的数据发送到 View,用户得到反馈
1.双向绑定技术,当Model变化时,View-Model会自动更新,View也会自动变化,能很好的做到数据一致性。
2.View的功能进一步的强化,具有控制的部分功能。
3.UI和逻辑的开发解耦。
model是原料 viewmodel做成蛋糕 view包上外包装放在柜台上
vue的nextTick
2.5 setImmediate -> MessageChannel -> setTimeout
2.6 Promise -> MutationObserver -> setImmediate -> setTimeout
vue中组件的通信
父组件通过props的方式向子组件传递数据,而通过$emit 子组件可以向父组件通信。
$children 的值是数组,而$parent是个对象
provide/ inject
ref / refs
eventbus
EventBus.$off('addition', {})
vuex
Proxy 的优势如下:
- Proxy 可以直接监听对象而非属性;
- Proxy 可以直接监听数组的变化;
- Proxy 有多达 13 种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具备的;
- Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的,而 Object.defineProperty 只能遍历对象属性直接修改;
- Proxy 作为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准的性能红利;
Object.defineProperty 的优势如下:
- 兼容性好,支持 IE9,而 Proxy 的存在浏览器兼容性问题,而且无法用 polyfill 磨平,因此 Vue 的作者才声明需要等到下个大版本( 3.0 )才能用 Proxy 重写。