ES6 Module
在 ES6 Module出现之前,有3种模块化方案
- AMD 浏览器端
- CMD 服务器端
- CommonJs 服务器端
ES6 Module export
- export {<变量>} 导出的是一个变量的引用,当变量改变时,import 导入的变量也会改变
- export default 导出的是一个值的拷贝,当变量改变是, import导入的变量不会改变
ES6 Module vs CommonJs 区别
- CommonJs 输出的是一个值的拷贝,ES6 Module种export {<变量>}输出的是一个变量的引用,export deafult 输出的是一个值的拷贝
- CommonJs运行在服务器上,运行时加载,ES6 Module时静态的输出一个接口,发生在编译的阶段
- CommonJs 在第一次加载的时候运行一次, 之后加载返回的都是第一次的结果,具有缓存的效果, ES6 Module 则没有
ES6 Module import
ES6 Module静态编译的特点,导致了无法动态加载,但是总是会有一些需要动态加载模块的需求,所以现在有一个提案,使用把import作为一个函数可以实现动态加载模块,它返回一个Promise,Promise被resolve时的值为输出的模块
import('./module.js').then(res=>{
...
})
Vue中路由的懒加载的ES6写法就是使用了这个技术
Proxy
Object.defineProperty的增强版
let obj = {}
obj = new Proxy(obj, {
set(target, key, val) {
console.log('oops')
return Reflect.set(target, key, val)
}
})
obj.foo = 'bar'
- handler.apply
apply 可以让我们拦截一个函数的执行,我们可以把它用在函数节流中
const proxy = (func, time) => {
let previous = new Date(0).getTime()
let handler = {
apply(target, context, args) {
let now = new Date().getTime()
if(now - previous > time) {
previous = now
Reflect.apply(func, context, args)
}
}
}
return new Proxy(func, handler)
}
DOM.addEventListener('mousemove', proxy(handler, TIME))
- handler.contruct
contruct 可以拦截通过new关键词调用这个函数的操作, 我们可以用在单例模式中
function proxy(func) {
let instance
let handler = {
construct(target, args) {
if(!instance) {
instance = Reflect.construct(func, args)
}
return instance
}
}
return new Proxy(func, handler)
}
function Person(name, age) {
this.name = name
this.age = age
}
const SingletonPerson = proxy(Person)
let person1 = new SingletonPerson('zhl', 22)
let person2 = new SingletonPerson('syw', 22) //这个实例不会生成
console.loa(person1 === person2) //true
- handler.defineProperty
defineProperty可以拦截对这个对象的Obeject.defineProperty操作
注意对象内部的默认的[[SET]]函数(即对这个对象的属性赋值)会间接触发defineProperty和getOwnPropertyDescriptor这2个拦截方法
function onChange(obj, callback) {
const handler = {
get(target, key) {
try{
return new Proxy(target[key], handler)
}catch(e) {
Reflect.get(target, key)
}
},
defineProperty(target, key, descriptor) {
callback()
return Reflect.defineProperty(target, key, descriptor)
}
}
return new Proxy(obj, handler)
}
let obj = onChange({}, () => {
console.log('oops')
})
obj.a = {} //'oops'
obj.a.b = 1 /'oops'
网友评论