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

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

hot3.png

 

字数: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 ,在类的注释上添加 标签表示静态类。静态类中包含一个方法 extend ,实现了一个简单的扩展功能,后面类的继承需要用到这个接口。(这里需要注意,静态类中,所有的成员也都是静态的。因此,所有的成员必须加上标签)。

 

/**     * 所有类的基类     * @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 ,该类不需要实现任何方法,所以,我们给他添加一个抽象标签 表明该类是一个抽象类。 GM.Class表明了该类派生自 GM.Class 类,标签表示此类是这个版本新增加的内容。

​ 类中有一个 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代码基本一致,这里就不再多做累述了。

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

3.1.2%E4%BB%A3%E7%A0%81%E7%BB%93%E6%9E%84%E6%88%AA%E5%9B%BE.png

 

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 ,就可以看到我们今天的劳动成果啦!

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

3.1.1%E6%96%87%E6%A1%A3%E9%A1%B5%E9%9D%A2%E6%88%AA%E5%9B%BE.png

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

 

​ 所有源码下载地址:

 

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

转载于:https://my.oschina.net/lsjcoder/blog/1592326

你可能感兴趣的文章
android download学习记录
查看>>
hdu 4542 数论 + 约数个数相关 腾讯编程马拉松复赛
查看>>
转: 关于Linux与JVM的内存关系分析
查看>>
[转]c++ 为什么要将基类的析构函数声明为Virtual?
查看>>
1px的border
查看>>
FFmpeg视频处理必备
查看>>
activity window view 关系
查看>>
muduo 与 libevent2 吞吐量对照
查看>>
SQL Server调优系列玩转篇三(利用索引提示(Hint)引导语句最大优化运行)
查看>>
hdoj 5113 Black And White DFS+剪枝
查看>>
iis7如何取消目录的可执行权限
查看>>
HTML5+javascript实现图片加载进度动画效果
查看>>
SSL/TLS协议运行机制的概述
查看>>
git push 提示
查看>>
[LeetCode] Spiral Matrix II 螺旋矩阵之二
查看>>
使用 Spring 进行单元测试
查看>>
C++ const、volatile、mutable的用法 (转)
查看>>
Python的模块调用
查看>>
Linux 计划任务 Crontab 笔记与总结(3)Crontab 配置文件
查看>>
C-printf/sprintf/snprintf中的类型转换详解
查看>>