• js --装饰者模式


    定义

    装饰者模式能够在补改变对象自身的基础上,在程序运行期间给对象动态的添加职责。

    当看到装饰者模式的定义的时候,我们想到的js 的三大特性之一--继承,不也能够实现不改变对象自身的基础上,添加动态的职责,也是可以实现的。那为什么还需要装饰者模式呢?在解决这个问题之前,先讲一下继承的概念。

    继承

    继承可以解决代码复用的问题,让编程更靠近人类的思维。当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过继承父类中的属性和方法。

    js 实现继承的方式:下面介绍几种常见的继承方式

    1.对象冒充 :对象冒充的意思就是获取那个类的所有成员,js调用哪个方法,就获取那个方法的所有。

    // 对象冒充
    function father(name, age) {
        this.name = name
        this.age = age
        this.show= function() {
            console.log('我叫' + this.name , '今年' + this.age)
        }
    }
    function son(name, age) {
        this.father = father
        this.father(name, age)
        this.showSon= function() {
            console.log('自己')
        }
    }
    let Son = new son('gmn', 18)
    Son.show() //我叫gmn 今年18

    2.原型链继承:将父类的实例作为子类的原型

    // 原型链继承
    function Father() {
    
    }
    Father.prototype.name = function(name) {
        this.name = name
        console.log('name', name)
    }
    Father.prototype.age = function(age) {
        this.age = age
    }
    function Son() {
        
    }
    Son.prototype =new Father()
    Son.prototype.name('gmn') // gmn

    特点:

    1. 非常纯粹的继承关系,实例是子类的实例,也是父类的实例
    2. 父类新增原型方法/原型属性,子类都能访问到
    3. 简单,易于实现

    缺点:

    1. 要想为子类新增属性和方法,必须要在new Animal()这样的语句之后执行,不能放到构造器中
    2. 无法实现多继承
    3. 来自原型对象的所有属性被所有实例共享
    4. 创建子类实例时,无法向父类构造函数传参

    在es6中也有extend 和class 来实现继承。其实,本质也是基于原型机制的。

    其实,继承会存在一些缺点:

    1.超类子类的强耦合,超类改变导致子类改变

    2.超类内部细节对子类可见,破坏了封装性

    3.完成功能复用的同时,可能会创造大量子类。

    也正是因为继承的缺点,才有了装饰者模式。关于继承的概念就先暂时讲这么多把,言归正传,继续说装饰者模式。

    例子:

    1.传统面向对象语言的实现方式

    // 原始类
    var
    Original = function () { }; Original.prototype.fire = function () { console.log('着火了'); }; //装饰类 var MissileDecorator = function (plan) { this.plan = plan; } MissileDecorator.prototype.fire = function () { this.plan.fire(); console.log('真的着火了'); }; var plan = new Original(); plan = new MissileDecorator(plan); plan.fire(); // 着火了 // 真的着火了

    这种方式的实现,室装饰器类要维护目标对象的一个引用,同时还是新啊目标类的所有接口哦。调用方法时,先执行目标对象原有的方法,在执行自行添加的特性。

    2.JS基于对象的实现方式

    var Original = {
        fire: function () {
            console.log('着火了');
        }
    };
    
    var missileDecorator= function () {
        console.log('真的着火了');
    };
    
    var fire = Original.fire;
    
    Original.fire=function () {
        fire();
        missileDecorator();
    };
     
    Original.fire(); 
    //着火了
    // 真的着火了

    装饰者模式将一个对象嵌入到另一个对象之中,实际上相当于这个对象被另一个对像包装起来,形成一条包装链。请求随着这条包装链依次传递到所有的对象,每个对象都有处理这条请求的机会。

    3,使用装饰者模式实现表单校验并提交:装饰着模式分离表单验证和提交的函数

    Function.prototype.before=function (beforefn) {
        var _this= this;                               //保存旧函数的引用
        return function () {                           //返回包含旧函数和新函数的“代理”函数
            beforefn.apply(this,arguments);            //执行新函数,且保证this不被劫持,新函数接受的参数
            // 也会被原封不动的传入旧函数,新函数在旧函数之前执行
            return _this.apply(this,arguments);
        };
    };
    
    var validata=function () {
        if(username.value===''){
            alert('用户名不能为空!')
            return false;
        }
        if(password.value===''){
            alert('密码不能为空!')
            return false;
        }
    }
    
    var formSubmit=function () {
        var param={
            username=username.value;
            password=password.value;
        }
    
        ajax('post','http://www.mn.com',param);
    }
    
    formSubmit= formSubmit.before(validata);
    
    
    submitBtn.onclick=function () {
        formSubmit();
    }

    总结

     装饰者模式是为以有功能动态的添加更多功能的一种方式,把每个要装饰的功能放在单独的函数里,然后用该函数包装所有装饰的已有函数对象,因此,当需要执行特殊行为的时候,调用代码就可以根据需要有选择的,按顺序的使用装饰功能来包装对象。优点事把类(函数)的核心职责和装饰功能区分开了

  • 相关阅读:
    git笔记
    初试linux,cp、rm、mv、file、umask等命令粗略使用方法
    Linux的rwx
    nano的简单笔记
    windows10访问ftp中文乱码怎么办?
    Windows 将FTP 映射到本地文件夹 --简化操作
    计算地址掩码
    Can't connect to MySQL server on localhost (10061)解决方法
    微信小程序开发入门学习(2):小程序的布局
    微信小程序开发入门学习(1):石头剪刀布小游戏
  • 原文地址:https://www.cnblogs.com/mn6364/p/11060681.html
Copyright © 2020-2023  润新知