单例模式
保证一个类仅有一个实例,并提供访问此实例的全局访问点。
const Singleton = function () {}
Singleton.getInstance = (function(){
//es6没有静态类型,利用闭包,函数外部无法访问instance
let instance = null;
return function(){
if(!instance){
instance = new Singleton()
}
//如果已经存在则直接返回
return instance
};
})()
let s1 = Singleton.getInstance()
let s2 = Singleton.getInstance()
console.log(s1===s2) //true
复制代码
工厂模式
工厂方法模式的实质是定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行。
class Dog { //实体类
run(){
console.log('Dog')
}
}
class Cat { //实体类
run(){
console.log('Cat')
}
}
class Animal{ //工厂类
constructor(name){
switch (name){
case 'Dog':
return new Dog();
case 'Cat':
return new Cat();
default:
throw TypeError('class name wrong')
}
}
}
const cat = new Animal('Cat')
cat.run()
const dog = new Animal('Dog')
dog.run()
复制代码
发布订阅模式
定义了对象之间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都可以得到通知。
// vue2.0响应式实现
//判断是否为对象
function isObject(obj) {
return typeof obj === 'object' && obj !== null
};
/**
* @param {*} obj
*/
//监听对象变化
function observe(obj) {
if (!isObject(obj)) {
return;
}
Object.keys(obj).forEach(key => {
var originValue = obj[key]
observe(originValue)
var dep = new Dep() //针对每一个属性创建一个依赖收集
Object.defineProperty(obj, key, {
get: function() {
// console.log('get' + originValue)
dep.depend()
return originValue
},
set: function(value) {
if (value !== originValue) {
// console.log('set', value)
originValue = value
observe(originValue)
dep.notify()
}
}
})
})
}
//test
var state = {
msg: 'hello',
mount: 10,
addstr: {
name: 'jiangyao',
age: 21
}
};
observe(state)
//依赖收集
function Dep() {
this.functions = new Set()
}
var activeFunction = null
//有某个函数在用我
Dep.prototype.depend = function() {
if (activeFunction) {
this.functions.add(activeFunction)
}
}
//通知用到这个函数的所有对象:我变了
Dep.prototype.notify = function() {
this.functions.forEach(fn => fn())
}
function autorun(fn) {
function functionWrapper() {
activeFunction = functionWrapper
fn()
activeFunction = null
}
functionWrapper()
}
autorun(() => {
app.innerHTML = `${state.msg}+${state.mount}` //添加到页面
})
复制代码
<div id="app"></div>
<script src="./vue响应式.js"></script>
复制代码
代理模式
为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
ES6所提供Proxy
构造函数能够让我们轻松的使用代理模式:
var proxy = new Proxy(target, handler);
target
要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
handler
一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p 的行为。
//简单实现验证
let validator = {
set: function(obj, prop, value) {
if (prop === 'age') {
if (!Number.isInteger(value)) {
throw new TypeError('The age is not an integer');
}
if (value > 200) {
throw new RangeError('The age seems invalid');
}
}
// The default behavior to store the value
obj[prop] = value;
// 表示成功
return true;
}
};
let person = new Proxy({}, validator);
person.age = 100;
console.log(person.age);
// 100
person.age = 'young';
// 抛出异常: Uncaught TypeError: The age is not an integer
person.age = 300;
// 抛出异常: Uncaught RangeError: The age seems invalid
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END