博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JSDuck实战
阅读量:6259 次
发布时间:2019-06-22

本文共 9518 字,大约阅读时间需要 31 分钟。

字数:2543

阅读时间:15分钟

前言

​ 上一篇文章我们讲述了JSDuck的详细用法。那么,本文笔者就以实例为基础,和大家一起,从零开始,搭建一个简单的API文档——我们的第一个API文档V0.0.1。

​ 上一篇文章的入口处 ===>

正文

​ 首先,我们确定框架的基本内容:一个动物基类,然后派生出猫和狗两个子类。动物基类中有一个动物描述属性和吃饭方法,其派生类猫拥有奔跑、玩耍两个方法,外加一个发出声音的事件。

​ 整体内容就这么多,非常简单哈,那下面我们就来看看该如何构建整个框架。

1.构建基础代码

​ 磨刀不误砍柴工,首先,我们需要构建好基础代码。根据所需内容确定,我们需要构建一套完整的创建类和继承类的方案。那么,第一步,我们创建一个base.js文件来盛放基础代码。

var GM = {};    window.GM = GM;    /**     * 基础类的通用API类     * @class GM.Util     * @author lsjcoder     * @docauthor lsjcoder     * @static     */    GM.Util = {        /**         * 扩展对象         * @method extend         * @static         * @param dest         *            {Object} 任意对象         * @return {Object} 扩展后的对象         */        extend : function(dest) { // (Object[, Object, ...]) ->            var sources = Array.prototype.slice.call(arguments, 1), i, j, len, src;            for (j = 0, len = sources.length; j < len; j++) {                src = sources[j] || {};                for (i in src) {                    if (src.hasOwnProperty(i)) {                        dest[i] = src[i];                    }                }            }            return dest;        }    };

​ 在创建好的文件内,我们先编写上述代码。我们先声明了类 GM.Util ,在类的注释上添加 @static标签表示静态类。静态类中包含一个方法 extend ,实现了一个简单的扩展功能,后面类的继承需要用到这个接口。(这里需要注意,静态类中,所有的成员也都是静态的。因此,所有的成员必须加上@static标签)。

/**     * 所有类的基类     * @class GM.Class     */    GM.Class = function() {        /**         * @property {String} version 版本号         * @readonly         */        this.version = "0.0.1";    };

​ 声明顶层基类 GM.Class ,框架中所有的类都派生自该类。类中声明了一个 version 属性,该属性是字符串类型,并且是只读属性。

/**     * 基类的扩展方法     * @method extend     * @static     * @param {Object}     *            props 包含需要扩展的成员的对象     * @return {Object} 扩展后的类     */    GM.Class.extend = function(props) {        // extended class with the new prototype        var NewClass = function() {            // call the constructor            if (this.initialize) {                this.initialize.apply(this, arguments);            }            // call all constructor hooks            if (this._initHooks) {                this.callInitHooks();            }        };        // instantiate class without calling constructor        var F = function() {        };        F.prototype = this.prototype;        var proto = new F();        proto.constructor = NewClass;        NewClass.prototype = proto;        // inherit parent's statics        for ( var i in this) {            if (this.hasOwnProperty(i) && i !== 'prototype') {                NewClass[i] = this[i];            }        }        // mix static properties into the class        if (props.statics) {            GM.Util.extend(NewClass, props.statics);            delete props.statics;        }        // mix includes into the prototype        if (props.includes) {            GM.Util.extend.apply(null, [ proto ].concat(props.includes));            delete props.includes;        }        // merge options        if (props.options && proto.options) {            props.options = GM.Util.extend({}, proto.options, props.options);        }        // mix given properties into the prototype        GM.Util.extend(proto, props);        proto._initHooks = [];        var parent = this;        // jshint camelcase: false        NewClass.__super__ = parent.prototype;        // add method for calling all hooks        proto.callInitHooks = function() {            if (this._initHooksCalled) {                return;            }            if (parent.prototype.callInitHooks) {                parent.prototype.callInitHooks.call(this);            }            this._initHooksCalled = true;            for (var i = 0, len = proto._initHooks.length; i < len; i++) {                proto._initHooks[i].call(this);            }        };        return NewClass;    };

​ 基类GM.Class中包含一个静态方法,用于实现类的继承机制。后续代码中类的封装和继承都是使用该方法完成的。

/**     * @enum GM.Enum.Sex 性别枚举     */    GM.Enum.Sex = {        /**         * 男         */        "0":"男",        /**         * 女         */        "1":"女"    }

​ 基础代码中,还声明了一个性别枚举,以供后续使用。

​ 至此,基础代码构建完毕。

2.构建动物基类代码

​ 在这个环节中,我们需要构建一个动物基类。首先,我们创建一个animal.js文件盛放代码。

​ 文件完整代码如下:

/**     * 动物类     * @class GM.Animal     * @alias Animal     * @abstract     * @extends GM.Class     * @new     * @author lsjcoder     * @docauthor lsjcoder     */    GM.Animal = GM.Class.extend({        /**         * @method constructor         * @cfg {Object} configs 传入参数         * @cfg {String} configs.name 姓名         * @cfg {Number} configs.age 年龄         * @cfg {"男"/"女"} configs.sex 性别         */        initialize:function(configs){            this.props.name = configs.name;            this.props.age = configs.age;            this.props.sex = configs.sex;        },        /**         * @property {Object} props 属性         * @property {String} props.name 姓名         * @property {Number} props.age 年龄         * @property {GM.Enum.Sex} props.sex 性别         * @property {String} props.color 颜色         * @property {String} props.type 品种         */        props:{            name:"",            age:0,            sex:"男",            color:"",            type:""        },        /**         * 吃饭         * @method eat         * @abstract         * @param  {String} food 食物         * @return {Boolean} 是否进食         */        eat:function(food){            if(food != null || food !== ""){                return true;            }            return false;        }    });

​ 我们创建了一个动物类 GM.Animal ,该类不需要实现任何方法,所以,我们给他添加一个抽象标签 @abstract表明该类是一个抽象类。@extends GM.Class表明了该类派生自 GM.Class 类,@new标签表示此类是这个版本新增加的内容。

​ 类中有一个 initialize 方法,它是类的构造函数。所以我们用注释 @method constructor标记它为构造函数,然后使用 @cfg标签描述构造函数所需参数。这里,构造函数所需参数是一个对象,对象中有多个属性,所以我们使用如上配置方式来分别描述每一个属性。类中还有一个 props 属性,描述了动物的基本信息,该属性也是一个对象,注释方式同上述 @cfg 。最后,类中还有抽象方法 eat ,该方法接收一个字符串类型参数并返回一个布尔类型的结果。

3.构建子类猫和狗的代码

​ 接下来,我们需要构建动物类的两个派生类:猫类和狗类。我们分别创建两个代码文件:cat.js、dog.js。

​ cat.js文件中代码如下:

/**     *猫     *      *```     *示例:     *var pCat = new GM.Cat({     *        name:"Kity",     *        age:1,     *        sex:"女"     *})     *```     *     * @class GM.Cat     * @extends GM.Animal     * @alias Cat     * @author lsjcoder     * @docauthor lsjcoder     * @uses GM.Dog     *          */    GM.Cat = GM.Animal.extend({        /**         * @method constructor         * @cfg {Object} configs 传入参数         * @cfg {String} configs.name 姓名         * @cfg {Number} configs.age 年龄         * @cfg {"男"/"女"} configs.sex 性别         */        initialize:function(configs){            this.props.name = configs.name;            this.props.age = configs.age;            this.props.sex = configs.sex;            /**             * @event say 发出叫声             * @param {GM.Cat} this 当前实例             * @param {String} value 叫声             */            this.fireEvent("say", this, value);        },        /**         * @method run 奔跑,已经废弃,请使用 {@link GM.Cat#startRun} 方法代替         * @removed         */        run:function(){            this.bRun = true;        },        /**         * @method startRun 开始奔跑         * @return {Boolean} 开始奔跑是否成功         */        startRun:function(){            if(this.bRun === true){                return false;            }            this.bRun = true;            return true;        },        /**         * @method playWithDog 与小狗一起玩耍         * @param  {GM.Dog} pDog 小狗         */        playWithDog:function(pDog){            this.player = pDog;        }    });

​ 类 GM.Cat 派生自GM.Animal ,其中需要强调的有以下几点:

*```     *示例:     *var pCat = new GM.Cat({     *        name:"Kity",     *        age:1,     *        sex:"女"     *})     *```

​ 这段注释是描述了一个使用该类的示例,使用的是markdown语法来注释的。在文字的首尾分别添加符号 "`" 就可以表明注释代码,但是注意该符号一定要换行使用,否则无法生效。

/**    * @event say 发出叫声    * @param {GM.Cat} this 当前实例    * @param {String} value 叫声    */    this.fireEvent("say", this, value);

​ 这段注释表明,类 GM.Cat 拥有一个名称为 “say” 的事件,该事件有两个参数,一个是当前实例,另外一个是字符串类型的叫声。

* @property {"男"/"女"} configs.sex 性别* @property {GM.Enum.Sex} props.sex 性别

​ 上面代码是描述枚举的两种方式。

​ dog.js代码和cat.js代码基本一致,这里就不再多做累述了。

​ 至此,我们所有的代码构建工作就结束了,整个代码结构如下图所示

图1

4.生成文档

​ 接下来,就是最后一步了——使用工具生成文档。

​ 我们在与代码同级的目录下,创建一个 jsduck.json 配置文件,以便工具使用。配置文件内容如下:

{    "--title": "我是一个示例文档",    "--welcome": "welcome.html",    "--warnings": ["-link", "-no_doc"],    "--seo": true,    "--": [        "./code"    ],    "--output": "./docs",    "--examples-base-url": "../examples",    "--examples": "./examples.json",    "--body-html": [        ""    ],    "--categories":"./categories.json"}

​ 我们配置输入文件为整个代码文件夹,解析所有代码并生成文档。这里,我们配置了一个 examples.json 文件作为示例配置文件,文件内容如下:

[    {        "title": "样例展示",        "items": [            {                "name": "test-example",                "title": "cat类使用示例",                "description": "cat类使用示例",                "url": "/example.html",                "icon": "user.png",                "status": "updated"            }        ]    }]

​ 这里,我们配置了 examples 目录下的 example.html 文件作为示例页面。

​ 然后,里面还配置了一个 categories.json 文件作为代码分类配置,文件内容如下:

[    {        "name": "Common",        "groups": [            {                "name": "Base",                "classes": [                    "GM.Class",                    "GM.Util"                ]            },            {                "name": "Animal",                "classes": [                    "GM.Animal",                    "GM.Cat",                    "GM.Dog"                ]            }        ]    }]

​ 该配置将代码中的类分为了两组:Base 和 Animal 。这里需要注意,JSDuck中代码分类配置限制死了,只能配三级结构,不能做其他级别的配置。

​ 好啦!至此,所有的准备工作就全部完成啦!

​ 此时,我们只需要在 jsduck.json 目录下,轻轻地输入命令 jsduck ,就可以看到随着命令执行的结束,同级目录下生成了一个 docs文件夹。这个文件夹就是我们的文档成果,进入该文件夹,打开页面 template.html ,就可以看到我们今天的劳动成果啦!

​ 晒一张成果图,与大家共勉:

图2

​ 关于JSDuck的学习和实践的分享,到这里就告一段落啦。希望对大家有所帮助,也随时欢迎大家和笔者讨论相关技术。

​ 所有源码下载地址:

欢迎关注我的微信公众号:

转载地址:http://yshsa.baihongyu.com/

你可能感兴趣的文章
spider RPC高级特性
查看>>
C# 导出资源文件到硬盘
查看>>
修复 ThinkPHP3.2.3 抛出异常模块的一个BUG,关闭字段缓存功能
查看>>
更改MySQL数据库的编码为utf8mb4
查看>>
android自动化测试--appium运行的坑问题及解决方法
查看>>
mysql Can’t connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock’
查看>>
TeamCity : .NET Core 插件
查看>>
Python 爬虫知识点 - XPath
查看>>
由数量众多照片拼贴而成的马赛克图片
查看>>
如何在linux Shell脚本里面把一个数组传递到awk内部进行处理
查看>>
共模电感的原理以及使用情况
查看>>
GridLookUpEdit多列模糊查询最简单方式 z
查看>>
memcache与Redis
查看>>
Python27中Json对中文的处理
查看>>
结构,是指事物自身各种要素之间的相互关联和相互作用的方式
查看>>
andoid电阻触摸移植
查看>>
备忘录模式
查看>>
U盘安装CentOS 7卡住在 mounting configuration file system
查看>>
《Java设计模式》之装饰模式
查看>>
android开发使用SQLite之写日记
查看>>