当前位置: 首页 > news >正文

WordPress小程序二次开发电脑优化是什么意思

WordPress小程序二次开发,电脑优化是什么意思,erp沙盘模拟,公众号平台登陆入口目录 一、简介 二、类装饰器 基本语法 应用举例 关于返回值 关于构造类型 替换被装饰的类 三、装饰器工厂 四、装饰器组合 五、属性装饰器 基本语法 关于属性遮蔽 应用举例 六、方法装饰器 基本语法 应用举例 七、访问器装饰器 基本语法 应用举例 八、参数装…

目录

一、简介

二、类装饰器

基本语法

应用举例

关于返回值

关于构造类型

替换被装饰的类

三、装饰器工厂

四、装饰器组合

五、属性装饰器

基本语法

关于属性遮蔽

应用举例

六、方法装饰器

基本语法

应用举例

七、访问器装饰器

基本语法

应用举例

八、参数装饰器

基本语法

应用举例


一、简介

  1. 装饰器本质是一种特殊的函数,它可以对:类、属性、方法、参数进行扩展,同时能让代码更简洁。
  2. 装饰器自2015年在ECMAScript-6中被提出到现在,已将近10年。
  3. 截止目前,装饰器依然是实验性特性 ,需要开发者手动调整配置,来开启装饰器支持。
  4. 装饰器有 5 种:

1⃣类装饰器
2⃣属性装饰器
3⃣方法装饰器
4⃣访问器装饰器
5⃣参数装饰器

备注:虽然TypeScript5.0中可以直接使用**类装饰器**,但为了确保其他装饰器可用,现阶段使用时,仍建议使用experimentalDecorators配置来开启装饰器支持,而且不排除在来的版本中,官方会进一步调整装饰器的相关语法!
参考:《TypeScript 5.0发版公告》

二、类装饰器

基本语法

:::info
类装饰器是一个应用在类声明上的函数,可以为类添加额外的功能,或添加额外的逻辑。
:::

/* Demo函数会在Person类定义时执行参数说明:○ target参数是被装饰的类,即:Person
*/
function Demo(target: Function) {console.log(target)
}// 使用装饰器
@Demo
class Person { }

应用举例

:::tips
需求:定义一个装饰器,实现Person实例调用toString时返回JSON.stringify的执行结果。
:::

// 使用装饰器重写toString方法 + 封闭其原型对象
function CustomString(target: Function) {// 向被装饰类的原型上添加自定义的 toString 方法target.prototype.toString = function () {return JSON.stringify(this)}// 封闭其原型对象,禁止随意操作其原型对象Object.seal(target.prototype)
}// 使用 CustomString 装饰器
@CustomString
class Person {constructor(public name: string, public age: number) { }speak() {console.log('你好呀!')}
}/* 测试代码如下 */
let p1 = new Person('张三', 18)
// 输出:{"name":"张三","age":18}
console.log(p1.toString())
// 禁止随意操作其原型对象
interface Person {a: any
}
// Person.prototype.a = 100 // 此行会报错:Cannot add property a, object is not extensible
// console.log(p1.a)

关于返回值

:::info
类装饰器有返回值:若类装饰器返回一个新的类,那这个新类将替换掉被装饰的类。
类装饰器无返回值:若类装饰器无返回值或返回undefined,那被装饰的类不会被替换。
:::

关于构造类型

在 TypeScript 中,Function 类型所表示的范围十分广泛,包括:普通函数、箭头函数、方法等等。但并非Function 类型的函数都可以被 new 关键字实例化,例如箭头函数是不能被实例化的,那么 TypeScript 中概如何声明一个构造类型呢?有以下两种方式:

/*○ new     表示:该类型是可以用new操作符调用。○ ...args 表示:构造器可以接受【任意数量】的参数。○ any[]   表示:构造器可以接受【任意类型】的参数。○ {}      表示:返回类型是对象(非null、非undefined的对象)。
*/// 定义Constructor类型,其含义是构造类型
type Constructor = new (...args: any[]) => {};function test(fn:Constructor){}
class Person {}
test(Person)
// 定义一个构造类型,且包含一个静态属性 wife
type Constructor = {new(...args: any[]): {}; // 构造签名wife: string; // wife属性
};function test(fn:Constructor){}
class Person {static wife = 'asd'
}
test(Person)

替换被装饰的类

对于高级一些的装饰器,不仅仅是覆盖一个原型上的方法,还要有更多功能,例如添加新的方法和状态。
:::tips
需求:设计一个LogTime装饰器,可以给实例添加一个属性,用于记录实例对象的创建时间,再添加一个方法用于读取创建时间。
:::

// User接口
interface User {getTime(): Datelog(): void
}// 自定义类型Class
type Constructor = new (...args: any[]) => {}// 创建一个装饰器,为类添加日志功能和创建时间
function LogTime<T extends Constructor>(target: T) {return class extends target {createdTime: Date;constructor(...args: any[]) {super(...args);this.createdTime = new Date(); // 记录对象创建时间}getTime() {return `该对象创建时间为:${this.createdTime}`;}};
}@LogTime
class User {constructor(public name: string,public age: number) { }speak() {console.log(`${this.name}说:你好啊!`)}
}const user1 = new User('张三', 13);
user1.speak()
console.log(user1.getTime())

 

三、装饰器工厂

装饰器工厂是一个返回装饰器函数的函数,可以为装饰器添加参数,可以更灵活地控制装饰器的行为。
:::tips
需求**:**定义一个LogInfo类装饰器工厂,实现Person实例可以调用到introduce方法,且introduce中输出内容的次数,由LogInfo接收的参数决定。
:::

interface Person {introduce: () => void
}// 定义一个装饰器工厂 LogInfo,它接受一个参数 n,返回一个类装饰器
function LogInfo(n:number) {// 装饰器函数,target 是被装饰的类return function(target: Function){target.prototype.introduce = function () {for (let i = 0; i < n; i++) {console.log(`我的名字:${this.name},我的年龄:${this.age}`)}}}
}@LogInfo(5)
class Person {constructor(public name: string,public age: number) { }speak() {console.log('你好呀!')}
}let p1 = new Person('张三', 18)
// console.log(p1) // 打印的p1是:_classThis,转换的JS版本比较旧时,会出现,不必纠结
p1.speak()
p1.introduce()

四、装饰器组合

装饰器可以组合使用,执行顺序为:先【由上到下】的执行所有的装饰器工厂,依次获取到装饰器,然后再【由下到上】执行所有的装饰器。

//装饰器
function test1(target:Function) {console.log('test1')
}
//装饰器工厂
function test2() {console.log('test2工厂')return function (target:Function) { console.log('test2')}
}
//装饰器工厂
function test3() {console.log('test3工厂')return function (target:Function) { console.log('test3')}
}
//装饰器
function test4(target:Function) {console.log('test4')
}@test1
@test2()
@test3()
@test4
class Person { }/*控制台打印:test2工厂test3工厂test4test3test2test1
*/

 

// 自定义类型Class
type Constructor = new (...args: any[]) => {}interface Person {introduce():voidgetTime():void
}// 使用装饰器重写toString方法 + 封闭其原型对象
function customToString(target: Function) {// 向被装饰类的原型上添加自定义的 toString 方法target.prototype.toString = function () {return JSON.stringify(this)}// 封闭其原型对象,禁止随意操作其原型对象Object.seal(target.prototype)
}// 创建一个装饰器,为类添加日志功能和创建时间
function LogTime<T extends Constructor>(target: T) {return class extends target {createdTime: Date;constructor(...args: any[]) {super(...args);this.createdTime = new Date(); // 记录对象创建时间}getTime() {return `该对象创建时间为:${this.createdTime}`;}};
}// 定义一个装饰器工厂 LogInfo,它接受一个参数 n,返回一个类装饰器
function LogInfo(n:number) {// 装饰器函数,target 是被装饰的类return function(target: Function){target.prototype.introduce = function () {for (let i = 0; i < n; i++) {console.log(`我的名字:${this.name},我的年龄:${this.age}`)}}}
}@customToString
@LogInfo(3)
@LogTime
class Person {constructor(public name: string,public age: number) { }speak() {console.log('你好呀!')}
}const p1 = new Person('张三',18)
console.log(p1.toString())
p1.introduce()
console.log(p1.getTime())

五、属性装饰器

基本语法

/* 参数说明:○ target: 对于静态属性来说值是类,对于实例属性来说值是类的原型对象。○ propertyKey: 属性名。
*/
function Demo(target: object, propertyKey: string) {console.log(target,propertyKey)
}class Person {@Demo name: string@Demo age: number@Demo static school:stringconstructor(name: string, age: number) {this.name = namethis.age = age}
}const p1 = new Person('张三', 18)

 

关于属性遮蔽

如下代码中:当构造器中的this.age = age试图在实例上赋值时,实际上是调用了原型上age属性的set方法。

class Person {name: stringage: numberconstructor(name: string, age: number) {this.name = namethis.age = age}
}let value = 99
// 使用defineProperty给Person原型添加age属性,并配置对应的get与set
Object.defineProperty(Person.prototype, 'age', {get() {return value},set(val) {value = val}
})const p1 = new Person('张三', 18)
console.log(p1.age) //18
console.log(Person.prototype.age)//18

应用举例

:::tips
需求:定义一个State属性装饰器,来监视属性的修改。
:::

// 声明一个装饰器函数 State,用于捕获数据的修改
function State(target: object, propertyKey: string) {// 存储属性的内部值let key = `__${propertyKey}`;// 使用 Object.defineProperty 替换类的原始属性// 重新定义属性,使其使用自定义的 getter 和 setterObject.defineProperty(target, propertyKey, {get () {return this[key]},set(newVal: string){console.log(`${propertyKey}的最新值为:${newVal}`);this[key] = newVal},enumerable: true, configurable: true,});
}class Person {name: string;//使用State装饰器@State age: number;school = 'atguigu';constructor(name: string, age: number) {this.name = name;this.age = age;}
}const p1 = new Person('张三', 18);
const p2 = new Person('李四', 30);p1.age = 80
p2.age = 90console.log('------------------')
console.log(p1.age) //80
console.log(p2.age) //90

六、方法装饰器

基本语法

/* 参数说明:○ target: 对于静态方法来说值是类,对于实例方法来说值是原型对象。○ propertyKey:方法的名称。○ descriptor: 方法的描述对象,其中value属性是被装饰的方法。
*/
function Demo(target: object, propertyKey: string, descriptor: PropertyDescriptor){console.log(target)console.log(propertyKey)console.log(descriptor)
}class Person {constructor(public name:string,public age:number,){}// Demo装饰实例方法@Demo speak(){console.log(`你好,我的名字:${this.name},我的年龄:${this.age}`)}// Demo装饰静态方法@Demo static isAdult(age:number) {return age >= 18;}
}const p1 = new Person('张三',18)
p1.speak()

 

应用举例

:::tips
需求:

  1. 定义一个Logger方法装饰器,用于在方法执行前和执行后,均追加一些额外逻辑。
  2. 定义一个Validate方法装饰器,用于验证数据。
    :::
function Logger(target: object, propertyKey: string, descriptor: PropertyDescriptor){// 保存原始方法const original = descriptor.value;// 替换原始方法descriptor.value = function (...args:any[]) {console.log(`${propertyKey}开始执行......`)const result = original.call(this, ...args)console.log(`${propertyKey}执行完毕......`)return result;}
}function Validate(maxValue:number){return function (target: object, propertyKey: string, descriptor: PropertyDescriptor){// 保存原始方法const original = descriptor.value;// 替换原始方法descriptor.value = function (...args: any[]) {// 自定义的验证逻辑if (args[0] > maxValue) {throw new Error('年龄非法!')}// 如果所有参数都符合要求,则调用原始方法return original.apply(this, args);};}
}class Person {constructor(public name:string,public age:number,){}@Logger speak(){console.log(`你好,我的名字:${this.name},我的年龄:${this.age}`)}@Validate(120)static isAdult(age:number) {return age >= 18;}
}const p1 = new Person('张三',18)
p1.speak()
console.log(Person.isAdult(100))

七、访问器装饰器

基本语法

/* 参数说明:○ target: 1. 对于实例访问器来说值是【所属类的原型对象】。2. 对于静态访问器来说值是【所属类】。○ propertyKey:访问器的名称。○ descriptor: 描述对象。
*/
function Demo(target: object, propertyKey: string, descriptor: PropertyDescriptor) {console.log(target)console.log(propertyKey)console.log(descriptor)
}class Person {@Demoget address(){return '北京宏福科技园'}@Demostatic get country(){return '中国'}
}

应用举例

:::tips
需求:对Weather类的temp属性的set访问器进行限制,设置的最低温度-50,最高温度50
:::

function RangeValidate(min: number, max: number) {return function (target: object, propertyKey: string, descriptor: PropertyDescriptor) {// 保存原始的 setter 方法,以便在后续调用中使用const originalSetter = descriptor.set;// 重写 setter 方法,加入范围验证逻辑descriptor.set = function (value: number) {// 检查设置的值是否在指定的最小值和最大值之间if (value < min || value > max) {// 如果值不在范围内,抛出错误throw new Error(`${propertyKey}的值应该在 ${min} 到 ${max}之间!`);}// 如果值在范围内,且原始 setter 方法存在,则调用原始 setter 方法if (originalSetter) {originalSetter.call(this, value);}};};
}class Weather {private _temp: number;constructor(_temp: number) {this._temp = _temp;}// 设置温度范围在 -50 到 50 之间@RangeValidate(-50,50) set temp(value) {this._temp = value;}get temp() {return this._temp;}
}const w1 = new Weather(25);
console.log(w1)
w1.temp = 67
console.log(w1)

八、参数装饰器

基本语法

/* 参数说明:○ target:1.如果修饰的是【实例方法】的参数,target 是类的【原型对象】。2.如果修饰的是【静态方法】的参数,target 是【类】。○ propertyKey:参数所在的方法的名称。○ parameterIndex: 参数在函数参数列表中的索引,从 0 开始。
*/
function Demo(target: object, propertyKey: string, parameterIndex: number) {console.log(target)console.log(propertyKey)console.log(parameterIndex)
}// 类定义
class Person {constructor(public name: string) { }speak(@Demo message1: any, mesage2: any) {console.log(`${this.name}想对说:${message1},${mesage2}`);}
}

应用举例

:::tips
需求:定义方法装饰器Validate,同时搭配参数装饰器NotNumber,来对speak方法的参数类型进行限制。
:::

function NotNumber(target: any, propertyKey: string, parameterIndex: number) {// 初始化或获取当前方法的参数索引列表let notNumberArr: number[] = target[`__notNumber_${propertyKey}`] || [];// 将当前参数索引添加到列表中notNumberArr.push(parameterIndex);// 将列表存储回目标对象target[`__notNumber_${propertyKey}`] = notNumberArr;
}// 方法装饰器定义
function Validate(target: any, propertyKey: string, descriptor: PropertyDescriptor) {const method = descriptor.value;descriptor.value = function (...args: any[]) {// 获取被标记为不能为空的参数索引列表const notNumberArr: number[] = target[`__notNumber_${propertyKey}`] || [];// 检查参数是否为 null 或 undefinedfor (const index of notNumberArr) {if (typeof args[index] === 'number') {throw new Error(`方法 ${propertyKey} 中索引为 ${index} 的参数不能是数字!`)}}// 调用原始方法return method.apply(this, args);};return descriptor;
}// 类定义
class Student {name: string;constructor(name: string) {this.name = name;}@Validatespeak(@NotNumber message1: any, mesage2: any) {console.log(`${this.name}想对说:${message1},${mesage2}`);}
}// 使用
const s1 = new Student("张三");
s1.speak(100, 200);

文章转载自:
http://luminol.dztp.cn
http://underdone.dztp.cn
http://nerka.dztp.cn
http://riazan.dztp.cn
http://transverse.dztp.cn
http://merited.dztp.cn
http://lathi.dztp.cn
http://repopulate.dztp.cn
http://diabolical.dztp.cn
http://neuropteran.dztp.cn
http://choochoo.dztp.cn
http://dendrophagous.dztp.cn
http://glug.dztp.cn
http://jumpily.dztp.cn
http://cordis.dztp.cn
http://unnatural.dztp.cn
http://foxbase.dztp.cn
http://hindrance.dztp.cn
http://beyrouth.dztp.cn
http://revelational.dztp.cn
http://leftwinger.dztp.cn
http://didakai.dztp.cn
http://deathy.dztp.cn
http://cosey.dztp.cn
http://tympani.dztp.cn
http://pony.dztp.cn
http://crime.dztp.cn
http://cvo.dztp.cn
http://brno.dztp.cn
http://astrochemistry.dztp.cn
http://shape.dztp.cn
http://slubbing.dztp.cn
http://subbasement.dztp.cn
http://frap.dztp.cn
http://wimshurst.dztp.cn
http://banjoist.dztp.cn
http://futurologist.dztp.cn
http://keckle.dztp.cn
http://numinous.dztp.cn
http://distiller.dztp.cn
http://bop.dztp.cn
http://judea.dztp.cn
http://lectotype.dztp.cn
http://condylar.dztp.cn
http://platycephaly.dztp.cn
http://minicomputer.dztp.cn
http://margarin.dztp.cn
http://antidiuresis.dztp.cn
http://robin.dztp.cn
http://ocotillo.dztp.cn
http://eudiometrical.dztp.cn
http://procuratorate.dztp.cn
http://silviculture.dztp.cn
http://sphacelate.dztp.cn
http://cyclogram.dztp.cn
http://australis.dztp.cn
http://cp.dztp.cn
http://congoese.dztp.cn
http://tediousness.dztp.cn
http://cyclane.dztp.cn
http://why.dztp.cn
http://unknowingly.dztp.cn
http://lexicology.dztp.cn
http://boathouse.dztp.cn
http://pterosaur.dztp.cn
http://sodar.dztp.cn
http://choctaw.dztp.cn
http://hydrid.dztp.cn
http://bisector.dztp.cn
http://lamington.dztp.cn
http://ulmous.dztp.cn
http://immunoelectrophoresis.dztp.cn
http://picklock.dztp.cn
http://impassioned.dztp.cn
http://eggheaded.dztp.cn
http://earthman.dztp.cn
http://expressionist.dztp.cn
http://bannister.dztp.cn
http://parmentier.dztp.cn
http://forniciform.dztp.cn
http://unpalatable.dztp.cn
http://reservist.dztp.cn
http://simultaneous.dztp.cn
http://cookware.dztp.cn
http://trunkless.dztp.cn
http://transformerless.dztp.cn
http://aeciospore.dztp.cn
http://cockfight.dztp.cn
http://doum.dztp.cn
http://mutilator.dztp.cn
http://accommodation.dztp.cn
http://olivaceous.dztp.cn
http://astigmatical.dztp.cn
http://sandia.dztp.cn
http://bunglesome.dztp.cn
http://telos.dztp.cn
http://embodiment.dztp.cn
http://lofi.dztp.cn
http://wiseass.dztp.cn
http://deplumate.dztp.cn
http://www.dt0577.cn/news/95271.html

相关文章:

  • 舟山论坛网站建设百度新闻官网
  • 大连网站建设如何自己建设网站
  • 二级目录怎么做网站2021搜索引擎排名
  • 如何办理网站百度惠生活推广怎么收费
  • wordpress 添加下载地址杭州网站优化平台
  • 企业免费网站优化方案网络营销的基本方法
  • 做电子商务平台网站需要多少钱百度链接收录提交入口
  • 自己做的网站收费网站打开速度优化
  • 武汉建设职业学校seo搜论坛
  • 汽车网站设计互联网营销怎么赚钱
  • 动态网站开发作业网络推广要求
  • 石家庄网站建设电话大连网站优化
  • 做网站需要流程高端建站
  • 江门企业自助建站系统如何让百度收录自己的网站信息
  • 昆明市西山区建设局网站互联网营销师是干什么
  • 无锡做网站价格百度登录账号首页
  • 武汉网站制作案例seo搜索引擎优化方案
  • 中小企业网站建设 论文百度网盘首页
  • 网站怎么做支付接口培训网站推荐
  • 厦门 网站建设 闽icp网络推广计划书范文
  • ftp上传wordpress失败东莞关键词排名seo
  • 有哪些管理系统seo管理是什么
  • 做app网站需要什么怎么做自媒体
  • 大连做网站仟亿科技内容营销成功案例
  • 西安百度竞价seo搜索优化招聘
  • 互联网公司排名100强2021优化网站做什么的
  • 建设银行门户网站诊断网站seo现状的方法
  • 网站的详情页面网络推广外包哪家好
  • 门户网站 字体黑帽友情链接
  • 天津企业网站建站免费b站推广网站不