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

无锡建行网站描述建设一个网站的具体步骤

无锡建行网站,描述建设一个网站的具体步骤,移动网站程序,foxmail网站邮箱注册Js中的装饰者模式 定义 装饰者模式也称为包装器模式,在不改变原有对象的基础上为其动态的添加上新的功能。 详细描述 在我们平时开发项目时想要扩展一个对象或者函数时(函数也是对象),可以直接修改原来的对象使其拥有新的功能…

Js中的装饰者模式

定义

装饰者模式也称为包装器模式,在不改变原有对象的基础上为其动态的添加上新的功能。

详细描述

在我们平时开发项目时想要扩展一个对象或者函数时(函数也是对象),可以直接修改原来的对象使其拥有新的功能,可是这样是不符合开放封闭原则的,而且随着业务越来越多目标对象会变的非常的庞大和复杂,变得难以维护。装饰者模式就是来解决这种问题,他会将新添加的功能定义为新的装饰类,然后使用装饰类来装饰(包装)一下原有对象,使原有对象可以轻易的拥有装饰类中的功能,并且自身不会改变。

举个现实中的例子,我们自己本身是一个对象,当天气冷的时候我会想穿上毛衣,下雨的时候在穿上雨衣,当天晴了以后在把他们脱掉。这里的毛衣和雨衣都可以看成是一个个装饰类,他们把我们本身的对象包装了一下使我们不怕冷并且还拥有防雨的功能,可是他们不是我们对象自身自带的,所以当我们需要和不需要的时候才可以更容易的自由使用和移除。如下图:
在这里插入图片描述

应用场景:

  • 当对象的功能需要动态的添加,又需要动态的撤销时。
  • 当需要对一系列功能进行排列组合时。
  • 当需要在现有功能前/后增加新的功能时。

代码实例

装饰对象
下面我们就来模拟实现一个穿衣服的实例,先不使用装饰者模式如下:

    
// 对象本身let self = {wear() {console.log('自身啥也没穿-光腚');},};// 穿上毛衣self = {wear() {console.log('自身啥也没穿-光腚');console.log('太冷了,赶紧穿上毛衣');},};// 穿上雨衣self = {wear() {console.log('自身啥也没穿-光腚');console.log('太冷了,赶紧穿上毛衣');console.log('妈呀还下雨了,在穿上雨衣');},};self.wear();// 打印// 自身啥也没穿-光腚// 太冷了,赶紧穿上毛衣// 妈呀还下雨了,在穿上雨衣

首先我们定义了一个自身对象-身上啥也没穿,此时太冷了要穿上毛衣就需要深入对象内部去修改来添加毛衣,下雨了想穿雨衣也需要去对象内部方法修改来增加穿上雨衣功能。也就是说每次功能的增加和减少都需要深入对象内部的方法去修改,只要深入对象内部修改就需要更多的考虑新的修改是否会对原来的代码有哪些影响。这样是不符合开放-封闭原则的。
下面我们看下装饰者模式的实现:

    // 对象本身const self = {wear() {console.log('自身啥也没穿-光腚');},};// 穿上毛衣const sweater = () => {console.log('太冷了,赶紧穿上毛衣');};// 穿上雨衣const raincoat = () => {console.log('妈呀还下雨了,在穿上雨衣');};const wear1 = self.wear;self.wear = function () {wear1();sweater();};const wear2 = self.wear;self.wear = function () {wear2();raincoat();};self.wear();// 打印// 自身啥也没穿-光腚// 太冷了,赶紧穿上毛衣
// 妈呀还下雨了,在穿上雨衣

上述代码根据js语言自身的特点,通过保存原引用的方式实现了功能的包装,但是自身对象原有的wear方法内部没有做任何改变,就可以拥有了穿上毛衣和雨衣的功能。

装饰函数

在js中函数也是对象,我们日常开发中充满了各种方法的提取封装修改等等,有的时候我们想在不改动函数本身的同时增加一些额外的功能。如我们想监听一下onload事件,并在事件触发时执行自己的逻辑,但是此时又不确定别人有没有已经绑定过onload事件,自己会不会把他们的覆盖,此时可以使用装饰者模式实现,如:

    window.onload = function () {console.log('我是不知道谁添加的功能');};// 通过引用地址保存原函数let _onload = window.onload || function () {};window.onload = function () {_onload(); // this指向console.log('我在onload事件中添加了自己的功能--hhhh');};

上面通过保存引用地址的方法实现装饰onload函数的功能,但是在执行的时候会有一些隐藏问题,比如_onload调用的时候其实函数的this指向会改变,这里只是因为刚好都指向window所以没有出问题,其他函数就需要手动的去绑定this指向比较费事。下面我们使用AOP切面函数来实现函数装饰,并且很好的解决这个问题。

AOP装饰函数

我们来使用AOP对函数进行装饰,使原函数执行之前/后添加新的功能,并且不改变原函数自身代码。
我们在来看下上面绑定onload事件的实现:

    // 定义AOP装饰函数Function.prototype.before = function (beforeFn) {const _self = this; // 保存原函数引用// 负责函数执行顺序return function (...params) {beforeFn.apply(this, params); // 插入之前函数执行_self.apply(this, params); // 执行原函数};
};window.onload = function () {console.log('我是不知道谁添加的功能');
};// 使用装饰函数装饰window.onload = (window.onload || function () {}).before(function () {console.log('我在onload事件中添加了自己的功能--hhhh');}).before(function () {console.log('我在添加一个功能2222');});// 打印// 我在添加一个功能2222// 我在onload事件中添加了自己的功能--hhhh// 我是不知道谁添加的功能

上述代码首先定义一个切片装饰函数,然后直接将需要添加的函数功能传入进去即可,而且还支持链式添加,更加的简洁方便。

虽然上面的方法已经很方便了但是还有个问题是我们直接在Function的原型上添加的方法,这样的话很可能会对原型中的属性造成污染,所以下面我们在实现一个例子并且去解决这个问题。比如我们实现一个小时吃饭的例子,妈妈警告我们吃饭之前必须洗手,想要出去玩必须先吃完饭。代码如下:

    const before = Symbol('before');const after = Symbol('before');// 定义AOP装饰函数Function.prototype[before] = function (beforeFn) {const _self = this; // 保存原函数引用// 负责函数执行顺序return function (...params) {beforeFn.apply(this, params); // 插入之前函数执行_self.apply(this, params); // 执行原函数};};// 定义AOP装饰函数Function.prototype[after] = function (afterFn) {const _self = this; // 保存原函数引用// 负责函数执行顺序return function (...params) {_self.apply(this, params); // 执行原函数afterFn.apply(this, params); // 插入之后函数执行};};let eat = function () {console.log('好好吃饭长高高');};const wash = function () {console.log('必须先洗手,不然不给吃饭');};const play = function () {console.log('终于吃完了,我要去玩玩玩玩');};eat = eat[before](wash)[after](play);eat();// 打印// 必须先洗手,不然不给吃饭// 好好吃饭长高高
// 终于吃完了,我要去玩玩玩玩

上面我们就实现了一个在吃饭行为之前通过包装拥有洗手行为,吃饭后去玩耍的例子,并且使用Symbol 语法解决了上述可能会污染函数原型的问题。

总结

优点

  • 可以动态的给原对象添加功能,非常灵活。
  • 添加新功能的同时不会修改原对象,符合开闭原则。
  • 装饰对象与原对象松耦合,易于维护。

缺点

  • 定义过多的装饰类,会增加系统的复杂性。

装饰者模式在我们日常开发中非常的有用,尤其是我们在接手一个新项目时,遇到一大堆代码时非常有用。

http://www.lbrq.cn/news/2408815.html

相关文章:

  • 优秀个人网站模板下载免费推广网站平台
  • 做网站哪家网站好艺人百度指数排行榜
  • 网站程序源码上传到空间打开网站首页还是显示的程序原源代码seo排名点击首页
  • 东莞新闻头条新闻今天seo软文代写
  • 做网站是个什么行业app拉新一手渠道
  • 做妈妈网站怎么赚钱优化大师官方下载
  • 花桥做网站合肥网站排名推广
  • 服务企业建设网站泉州关键词优化报价
  • 做盗版小说网站违法吗网站外链出售
  • e龙岩官网下载seo结算系统
  • 网站点赞怎么做的网络外贸推广
  • 2m带宽可以做音乐网站免费做网站的平台
  • logo制作步骤seo是什么意思的缩写
  • 锦州建设工程信息网站优化网站哪个好
  • 石家庄造价信息网杭州seo运营
  • 什么静态网站容易做怎样创建网站或者网址
  • 网上商城电商项目的管理步骤网站推广seo是什么
  • 虎门外贸网站建设公司pc优化工具
  • 网站开发如何建设公共页面百度 搜索热度
  • 建行官方网站多少钱怎样自己做网站
  • 扬中人电脑系统优化工具
  • 网站一直没有收录关键词优化哪个好
  • 成都搭建网站seo快速推广窍门大公开
  • 网站后台更新 前台为啥没反应竞价托管咨询微竞价
  • 网站设计提成多少钱四种基本营销模式
  • 深圳企业网站建设哪家好商旅100网页版
  • 一个域名可以做几个网站网站如何推广营销
  • 怎样在线做网站404百度的营销策略
  • 寻找网站建设 网站外包长尾关键词什么意思
  • 互联网品牌有哪些seo技术外包
  • Linux系统中全名、用户名、主机名的区别
  • 【Lua】大G表
  • 从TPACK到TPACK - AI:人工智能时代教师知识框架的重构与验证
  • 周末总结(2024/07/19)
  • NX二次开发常用函数坐标转化UF_MTX4_csys_to_csys和UF_MTX4_vec3_multipl
  • Django母婴商城项目实践(十一)- 用户信息模块之用户登录注册