杂七杂八的知识点整理

94 阅读5分钟

当属性名称与变量名称不一致的,需要显式的指定属性名。这样才能把属性值给赋值到变量中。
例如:

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的区别如下

  1. for ... of只能用在可迭代对象上,获取的是迭代器返回的value值,for ... in 可以获取所有对象的键名
  2. for ... in会遍历对象的整个原型链,性能非常差不推荐使用,而for ... of只遍历当前对象不会遍历它的原型链
  3. 对于数组的遍历,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执行一个文件时,会给这个文件内生成一个 exportsmodule对象,
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

  1. export与export default均可用于导出常量、函数、文件、模块等
  2. 在一个文件或模块中,export、import可以有多个,export default仅有一个
  3. 通过export方式导出,在导入时要加{ },export default则不需要
  4. export能直接导出变量表达式,export default不行。

export {<变量>}导出的是一个变量的引用,export default导出的是一个值的拷贝

  1. CommonJs在第一次加载的时候运行一次并且会生成一个缓存,之后加载返回的都是缓存中的内容

关于ES6 Module静态编译的特点,导致了无法动态加载,但是总是会有一些需要动态加载模块的需求,所以现在有一个提案,使用把import作为一个函数可以实现动态加载模块,它返回一个Promise,Promise被resolve时的值为输出的模块

Vue中路由的懒加载的ES6写法就是使用了这个技术,使得在路由切换的时候能够动态的加载组件渲染视图

image.png

  1. View 传送指令到 Controller
  2. Controller 完成业务逻辑后,要求 Model 改变状态
  3. Model 将新的数据发送到 View,用户得到反馈

image.png

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是个对象

provideinject

ref / refs

eventbus

EventBus.$off('addition', {})

vuex

image.png

Proxy 的优势如下:

  • Proxy 可以直接监听对象而非属性;
  • Proxy 可以直接监听数组的变化;
  • Proxy 有多达 13 种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具备的;
  • Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的,而 Object.defineProperty 只能遍历对象属性直接修改;
  • Proxy 作为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准的性能红利;

Object.defineProperty 的优势如下:

  • 兼容性好,支持 IE9,而 Proxy 的存在浏览器兼容性问题,而且无法用 polyfill 磨平,因此 Vue 的作者才声明需要等到下个大版本( 3.0 )才能用 Proxy 重写。