版权声明:本文为作者的原创文章,未经允许不得转载。 https://blog.csdn.net/lin5165352/article/details/81878836
- 装饰器模式
演示代码
class Circle{
draw(){
console.log('绘制一个圆形')
}
}
class Decorator{
constructor(circle){
this.circle = circle
}
draw(){
this.circle.draw()
this.setRedBouder(circle)
}
setRedBouder(circle){
console.log('设置红色边框')
}
}
let circle = new Circle()
circle.draw()
let dec = new Decorator(circle)
dec.draw()
在ES7中添加了装饰类。但是目前我们用的ES6还不支持。我们可以通过babel插件来演示。
安装插件: npm install babel-plugin-transform-decorators-legacy --save-dev
配置插件。
//装饰器模式
class Circle{
draw(){
console.log('绘制一个圆形')
}
}
class Decorator{
constructor(circle){
this.circle = circle
}
draw(){
this.circle.draw()
this.setRedBouder(circle)
}
setRedBouder(circle){
console.log('设置红色边框')
}
}
let circle = new Circle()
circle.draw()
let dec = new Decorator(circle)
dec.draw()
//演示1
@testDec
class Demo{
}
function testDec(target){
target.isDec = true
}
console.log(Demo.isDec)
//演示二 把属性变成只读
function readonly(target, name, descriptor){
descriptor.writable = false
return descriptor
}
class Person {
constructor(){
this.first = '张'
this.last = '三'
}
@readonly
name(){
return `${this.first} ${this.last}`
}
}
let p = new Person()
console.log(p.name())
// p.name = function(){
// return `AABB`
// }
//console.log(p.name()) //修改name会报错,提示name属性只读
//演示三 装饰方法 在前面先打印一下日志 再执行加法
function log(target,name,descriptor){
let oldValue = descriptor.value
descriptor.value = function(){
console.log(`calling ${name} with `,arguments)
return oldValue.apply(this.arguments)
}
return descriptor
}
class Math{
@log
add(a,b){
return a+b
}
}
let math = new Math()
const result = math.add(2,3)
console.log('result',result)
core-decorators是第三方开源lib,提供常用的装饰器。可以直接拿来使用和借鉴,不要自己再去摸索。
参考文档:github.com./jayphelps/core-decorators
npm install core-decorators --save
参考文档中给出了很多方法,可以自己研究。下面演示两种方法。一个是装饰成只读模式。一个是是装饰成废弃模式。
import { readonly } from 'core-decorators'
import { deprecate } from 'core-decorators'
//引用类库 就不需要自己再定义了
class Person {
@readonly
name() {
return '张三'
}
}
let p = new Person
console.log(p.name())
//p.name = function(){} //会报错 只读模式
class People {
// 打印默认提示内容:DEPRECATION People#name: This function will be removed in future versions.
// @deprecate()
// 也打印自定义的内容:DEPRECATION People#name: 该方法即将弃用
// See https://github.com/jayphelps/core-decorators for more details.
@deprecate('该方法即将弃用',{url:'https://github.com/jayphelps/core-decorators'})
name() {
return '李四'
}
}
let peo = new People();
peo.name()
- 代理模式
//代理模式 演示通过代理模式访问外网图片
class ReadImg{
constructor(fileName){
this.fileName = fileName
this.loadFromDisk()
}
display(){
console.log('display....'+this.fileName)
}
loadFromDisk(){
console.log('loading...'+this.fileName)
}
}
class ProxyImg{
constructor(fileName){
this.realImg = new ReadImg(fileName)
}
display(){
this.realImg.display()
}
}
let proxy = new ProxyImg('cat.jpg')
proxy.display()
//ES6中 proxy
//明星
let star = {
name: '李寻欢',
age:28,
phone:'15296002163'
}
//经纪人
let agent = new Proxy(star,{
get:function(target,key){
if(key === 'phone'){
return '152-1233-9087' //返回经纪人电话
}
if(key === 'price'){
return 120000
}
return target[key]
},
set:function(target,key,val){
if(key === 'customPrice'){
if(val < 100000){
throw new Error('价格太低,免谈')
}else{
target[key] = val
return true
}
}
}
})
console.log(agent.name)
console.log(agent.age)
console.log(agent.phone)
console.log(agent.price)
console.log(agent.high)
agent.customPrice = 150000
console.log('agent.customPrice',agent.customPrice)
agent.customPrice = 90000
console.log('agent.customPrice',agent.customPrice)
ES6 中引入了Proxy语法。
- 外观模式
00