ArcGIS API for JavaScript 4.15系列(8)——Dojo中类的定义

news2024/11/17 12:41:48

1、前言

JavaScript本质上是基于原型继承的一种编程语言,在ES6标准出现以前,JavaScript定义类的方式往往让人很难理解。而Dojo则很好地解决了这个问题。开发者可以通过dojo/_base/declare模块定义类,也可以通过define引用各个类模块。本文就来介绍一下如何在Dojo中实现面向对象的相关操作。

2、定义一个类

Dojo中,开发者只需要引入dojo/_base/declare模块即可定义类,declare定义类的其中一种写法如下所示,第一个参数表示要创建的类的名称,第二个参数表示该类的父类名称,如果父类不存在则赋值为null,第三个参数是一个json对象,主要用于定义类的成员变量和成员方法方法。

return declare('类名称', 父类, {
    // 成员变量
    // 构造函数
    // 成员方法
})

如果希望直接在require方法中直接定义类,也可以参考如下写法:

var= declare(父类, {
    // 成员变量
    // 构造函数
    // 成员方法
})

下面代码定义了一个简单的Person类:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>demo</title>
    <script src="http://localhost/arcgis_js_api/library/4.15/dojo/dojo.js"></script>
</head>
<body>
    <script>
        require(['dojo/_base/declare'], function (declare) {
            // 定义Person类
            var Person = declare(null, {
                name: null,      // 姓名
                gender: null,    // 性别
                age: null,       // 年龄

                // 构造函数
                constructor: function (name, gender, age) {
                    this.name = name;
                    this.gender = gender;
                    this.age = age;
                },

                // 定义方法,打印输出
                print: function () {
                    console.log('姓名:' + this.name + '\r\n性别:' + this.gender + '\r\n年龄:' + this.age);
                }
            })

            // 创建Person类
            var person = new Person('张三', '男', 30);
            person.print();
        });
    </script>
</body>
</html>

在上面的代码中,namegenderagePerson类的成员变量,constructor表示Person类的构造函数,该函数主要用处初始化成员变量,print是一个成员方法,实例化Person类后即可在外部进行调用。程序运行结果如下所示:

姓名:张三
性别:男
年龄:30

3、类的构造函数

构造函数一般用来初始化成员变量,上面的代码采用了如下写法来定义构造函数:

constructor: function (name, gender, age) {
    this.name = name;
    this.gender = gender;
    this.age = age;
}

熟悉JavaC#的同志对这种写法应该不会陌生,但这种写法存在一个问题,那就是一旦构造函数中的参数较多,则代码的可读写会变得很差。例如下面这种情况:

constructor: function (name, gender, age, email, phone, birthOfTime, address) {
    this.name = name;
    this.gender = gender;
    this.age = age;
    this.email = email;
    this.phone = phone;
    this.birthOfTime = birthOfTime;
    this.address = address;
}

当前很多JavaScript框架在实例化类时,都会在构造函数中传入一个json对象去初始化变量,那么Dojo是否也支持这种做法呢?答案当然是可以的,我们可以调用declare.safeMixin方法实现,现在将上面的代码修改一下:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>demo</title>
    <script src="http://localhost/arcgis_js_api/library/4.15/dojo/dojo.js"></script>
</head>
<body>
    <script>
        require(['dojo/_base/declare'], function (declare) {
            // 定义Person类
            var Person = declare(null, {
                name: null,      // 姓名
                gender: null,    // 性别
                age: null,       // 年龄

                // 构造函数
                constructor: function (args) {
                    declare.safeMixin(this, args);
                },

                // 定义方法,打印输出
                print: function () {
                    console.log('姓名:' + this.name + '\r\n性别:' + this.gender + '\r\n年龄:' + this.age);
                }
            })

            // 创建Person类
            var person = new Person({
                name: '张三',
                gender: '男',
                age: 30
            });
            person.print();
        });
    </script>
</body>
</html>

declare.safeMixin(this, args)大大简化了构造函数的定义流程,我们只需要在创建Person类时传入一个json对象即可实现成员变量的初始化操作:

var person = new Person({
    name: '张三',
    gender: '男',
    age: 30
});

程序运行结果如下所示:

姓名:张三
性别:男
年龄:30

4、类的模块化

在上面的代码中,我们直接在require方法中定义Person类。而实际工程往往包含众多的类,如果采用上面的做法,require方法将会变得异常臃肿,因此我们需要对类进行模块化处理。Dojo中使用define方法定义模块,创建一个JavaScript文件,取名为Person.js,在Person.js中加入如下代码:

define(['dojo/_base/declare'], function (declare) {
    return declare('Person', null, {
        name: null,      // 姓名
        gender: null,    // 性别
        age: null,       // 年龄

        // 构造函数
        constructor: function (args) {
            declare.safeMixin(this, args);
        },

        // 定义方法,打印输出
        print: function () {
            console.log('姓名:' + this.name + '\r\n性别:' + this.gender + '\r\n年龄:' + this.age);
        }
    })
})

找到IIS下部署ArcGIS API for JavaScript开发包的路径:C:\inetpub\wwwroot\arcgis_js_api\library\4.15\dojo,在该路径下新建一个文件夹,取名为js,如下图所示:

在这里插入图片描述

Person.js文件放入新建的js文件夹

在这里插入图片描述

最后在require方法中引用Person.js即可,代码如下:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>demo</title>
    <script src="http://localhost/arcgis_js_api/library/4.15/dojo/dojo.js"></script>
</head>
<body>
    <script>
        require(['dojo/_base/declare', 'js/Person'], function (declare, Person) {
            var person = new Person({
                name: '张三',
                gender: '男',
                age: 30
            });
            person.print();
        });
    </script>
</body>
</html>

程序运行结果如下所示:

姓名:张三
性别:男
年龄:30

5、类的自定义模块配置

上面的类模块化操作很好地解决了类的创建和管理问题。但相信你也发现它的问题:难道开发调试阶段每次新建或修改一个js文件都要把它复制到IIS目录下吗?这未免也太繁琐了一点。在实际开发过程中,我们一般会借助dojoConfig进行自定义模块配置。首先在工程中创建一个js文件夹,然后新建一个Person.js文件,如下图所示:

在这里插入图片描述

Person.js中加入如下代码:

define(['dojo/_base/declare'], function (declare) {
    return declare('Person', null, {
        name: null,      // 姓名
        gender: null,    // 性别
        age: null,       // 年龄

        // 构造函数
        constructor: function (args) {
            declare.safeMixin(this, args);
        },

        // 定义方法,打印输出
        print: function () {
            console.log('姓名:' + this.name + '\r\n性别:' + this.gender + '\r\n年龄:' + this.age);
        }
    })
})

然后在html页面中加入dojoConfig配置,代码如下:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>demo</title>
    <script>
        var dojoConfig = {
            async: true,
            packages: [{
                name: "js",
                location: location.pathname.replace(/\/[^/]*$/, '') + '/js'
            }]
        };
    </script>
    <script src="http://localhost/arcgis_js_api/library/4.15/dojo/dojo.js"></script>
</head>
<body>
    <script>
        require(['dojo/_base/declare', 'js/Person'], function (declare, Person) {
            var person = new Person({
                name: '张三',
                gender: '男',
                age: 30
            });
            person.print();
        });
    </script>
</body>
</html>

程序运行结果如下所示:

姓名:张三
性别:男
年龄:30

dojoConfig中的packages参数为数组类型,它可以定义一个或多个自定义的存放js文件的路径。在上面的代码中,location参数用于获取当前项目下js文件夹的相对路径。name可理解为命名空间,它的名称可以自行定义,下面的代码将name设置为ABCD,相对应的require中也许要改为'ABCD/Person'

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>demo</title>
    <script>
        var dojoConfig = {
            async: true,
            packages: [{
                name: "ABCD",
                location: location.pathname.replace(/\/[^/]*$/, '') + '/js'
            }]
        };
    </script>
    <script src="http://localhost/arcgis_js_api/library/4.15/dojo/dojo.js"></script>
</head>
<body>
    <script>
        require(['dojo/_base/declare', 'ABCD/Person'], function (declare, Person) {
            var person = new Person({
                name: '张三',
                gender: '男',
                age: 30
            });
            person.print();
        });
    </script>
</body>
</html>

程序运行结果如下所示:

姓名:张三
性别:男
年龄:30

6、类的继承

类的继承机制也是Dojo的一大亮点,在ArcGIS API for JavaScript的开发中,我们经常会继承dijit中的一些组件,然后对其进行扩展。此时就需要使用类的继承机制。Dojo中允许单继承和多继承,先来看一段单继承的代码:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>demo</title>
    <script src="http://localhost/arcgis_js_api/library/4.15/dojo/dojo.js"></script>
</head>
<body>
    <script>
        require(['dojo/_base/declare'], function (declare) {
            // 定义父类ClassA
            var ClassA = declare(null, {
                propertyA: 'This is A',
                print: function () {
                    console.log(this.propertyA);
                }
            })

            // 定义子类ClassB
            var ClassB = declare(ClassA, {
                propertyB: 'This is B',
                print: function () {
                    console.log(this.propertyA + '\r\n' + this.propertyB);
                }
            })

            // 创建ClassB实例
            var obj = new ClassB();
            obj.print();
        });
    </script>
</body>
</html>

在上面的代码中,ClassA为父类,子类ClassB继承ClassA,这意味着ClassB中会包含ClassA中的propertyA属性和print方法,同时ClassB又定义了属于自身的propertyB属性,并且重写了print方法,因此程序运行结果如下所示:

This is A
This is B

Dojo中的多继承也很简单,代码如下:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>demo</title>
    <script src="http://localhost/arcgis_js_api/library/4.15/dojo/dojo.js"></script>
</head>
<body>
    <script>
        require(['dojo/_base/declare'], function (declare) {
            // 定义父类ClassA
            var ClassA = declare(null, {
                propertyA: 'This is A'
            })

            // 定义父类ClassB
            var ClassB = declare(null, {
                propertyB: 'This is B'
            })

            // 定义子类ClassC
            var ClassC = declare([ClassA, ClassB], {
                propertyC: 'This is C',
                print: function () {
                    console.log(this.propertyA + '\r\n' + this.propertyB + '\r\n' + this.propertyC);
                }
            })

            // 创建ClassC实例
            var obj = new ClassC();
            obj.print();
        });
    </script>
</body>
</html>

程序运行结果如下所示:

This is A
This is B
This is C

总的来说,Dojo中的继承机制还是比较简单的,只需要记住一个原则即可,那就是继承链中的子类会不断覆盖父类的成员变量和成员方法。

7、结语

本文主要介绍了Dojo中关于类的相关操作。在Dojo中,类的定义十分简单,只需要引入dojo/_base/declare模块即可,而类的继承机制则能方便开发者对原有的组件进行功能扩展。因此个人觉得ArcGIS API for JavaScript选择基于Dojo构建并不是没有道理,这种严格面向对象的思想不仅严谨,同时也能方便项目的维护和管理。如果希望玩转ArcGIS API for JavaScript开发,同志们很有必要深入了解Dojo中的模块化思想。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/353737.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Swift基础语法 - 可选项

可选项&#xff08;Optional&#xff09; 可选项&#xff0c;一般也叫可选类型&#xff0c;它允许将值设置为 nil 在类型名称后面加个问号 ? 来定义一个可选项 var name: String? "CSDN" name nilvar age: Int? //默认就是nil age 30 age nilvar array [2,…

提升电脑运行速度,看这里就够了!

电脑是我们经常使用的工具之一&#xff0c;但是它却很容易出现问题&#xff0c;比如运行速度过慢&#xff0c;那么要如何提升电脑运行速度呢&#xff1f;方法1. 通过系统配置设置启动项1. 按下组合键“WinR”打开“运行”&#xff0c;在运行中输入“msconfig”然后按“回车”。…

LVGL-基于Windows系统Visual Studio模拟器搭建

LVGL-基于Windows系统Visual Studio模拟器搭建简述下载安装Visual Studio下载LVGL源码运行效果简述 LVGL是一个轻量级多功能图形库 丰富且强大的模块化图形组件&#xff1a;按钮 (buttons)、图表 (charts)、列表 (lists)、滑动条 (sliders)、图片 (images) 等高级的图形引擎&…

UUID简介以及java代码获取UUID示例

什么是UUIDUUID 是指&#xff08;UniversallyUnique Identifier&#xff09;通用唯一识别码&#xff0c;128位。RFC 4122描述了具体的规范实现。现实问题我们开发的时候&#xff0c;数据库表总会有一个主键&#xff0c;以前我们可能会使用自增的数字作为主键。这样做去确实查询…

PyTorch使用Visdom绘制训练过程曲线

最近在训练网络&#xff0c;网络的损失和准确率都是在终端输出的&#xff0c;很不直观&#xff0c;也看不出变化&#xff0c;就想着有没有一种工具可以实现实时的绘制模型的训练过程&#xff0c;然后就搜到了Visdom&#xff0c;发现这是个好东西啊&#xff0c;完全满足了我的需…

【Kafka】二.Kafka消息发布/消费流程

Kafka 通过对消费方进行分组管理来支持消息一写多读。 我画的图&#xff1a;工具&#xff08;processon在线画图&#xff09; 这个 Topic 分为 4 个 Partition&#xff0c;就是图中的 P1到 P4&#xff0c;上部的生产方根据规则选择一个 Partition 进行写入&#xff0c;默认规则…

算法练习-链表(一)

算法练习-链表&#xff08;一&#xff09; 文章目录算法练习-链表&#xff08;一&#xff09;解题技巧1. 实现链表1.1 节点的定义1.2 链表的遍历1.3 节点的查找1.4节点的插入1.4.1 链头插入1.4.2 链尾插入1.4.3 在给定节点之后插入1.5 删除节点1.5.1 删除给定节点之后的节点、1…

如何快速完成园区数据的可视化分析?

对于园区运营方来说&#xff0c;如果没有专业针对性的管理方案以及管理系统辅助的话&#xff0c;实现园区可视化管理的难度非常大&#xff0c;而且操作成本会很高。但如果园区运营方选择引进快鲸智慧楼宇推出的园区数据孪生可视化管理系统的话就会简单很多。 快鲸智慧楼宇数据孪…

python项目使用pipenv管理环境,如何使用pycharm调试模式

写在开始 了解pipenv的朋友们应该知道&#xff0c;使用pipenv管理项目环境后&#xff0c;仅pipenv虚拟环境中安装有项目的依赖包&#xff0c;测试机本身并没有安装这个依赖包&#xff0c;这就是pipenv使用的意义。但是&#xff0c;如果想要进入调试模式呢&#xff1f;我们要如…

Coqui TTS docker 使用记录

前言 之前介绍过 Coqui TTS 的安装&#xff0c;不过那个环境被我玩挂掉了…… 这次记录一下 docker 版本的使用。 参考网址&#xff1a;Docker images - TTS 0.11.1 documentation 正文 首先按照官网指示先把镜像 pull 下来。&#xff08;后记&#xff1a;确保 GPU driver…

重生之我是赏金猎人-番外篇-记一次层层突破的攻防演练

0x00 前言 本文简单记述了一下本人在某攻防演练过程中一次层层突破的有趣经历 技术性一般&#xff0c;但是层层突破属实艰难&#xff0c;并用到了比较多的思路&#xff0c;还望各位大佬多多指教 0x01 SSO账号获取 由于目标是某大学&#xff0c;对外开放的服务基本上都是一些…

CSS 预处理工具 Less 的介绍及使用 步骤

文章目录Less是什么Less的使用方法Less 中的注释Less 中的变量Less 中的嵌套Less 中的混合&#xff08;Mixin&#xff09;Less 中的运算Less 中的转译Less 中的作用域Less 中的导入Less实用实例文字超出省略文字垂直居中定位上下左右居中Less是什么 Less 是一门 CSS 预处理语言…

spring的事务控制

1.调用这个方法的对象是否是spring的代理对象&#xff08;$CGLIB结尾的&#xff09; 2.这个方法是否是加了Transactional注释 都符合才可以被事物控制 如果调用方法的对象没有被事物控制&#xff0c;那么被调用的方法即便是加了Transactional也是没用的 事务失效情况&#xf…

基于MATLAB计算MIMO信道容量(附完整代码与分析)

目录 一.介绍 二. 代码 三. 运行结果及分析 3.1 MIMO信道容量&#xff1a;固定发射天线数为4 3.2 MIMO信道容量&#xff1a;固定接收天线数为4 3.3 AWGN信道与瑞利信道容量 四. 总结 一.介绍 本文章将在MATLAB环境中分析MIMO信道容量&#xff0c;AWGN信道容量&#xf…

秒懂SpringBoot之全网最易懂的Spring Security教程

[版权申明] 非商业目的注明出处可自由转载 出自&#xff1a;shusheng007 文章目录概述简介原理默认实现使用Token认证方案JWT认证流程自定义Authentication Provider自定义Provider修改配置认证失败与授权失败处理认证失败处理授权失败处理支持方法级别的授权总结源码概述 现如…

PMP好考吗,有多大的价值?

关于PMP考试题型及考试内容&#xff0c;PMP考试共200道单选题&#xff0c;其中25道题不计分&#xff0c;会被随机抽查&#xff0c;答对106道题以上通过考试&#xff0c;参考比例106/175&#xff0c;60.57%估计答对&#xff08;10625&#xff09;道题及上即可通过&#xff0c;参…

全国进入裁员潮,到底是大厂难混?还是我技不如人?

前言 面对裁员&#xff0c;每个人的心态不同。他们有的完全没有料想到自己会被裁&#xff0c;有的却对裁员之事早有准备。大多数人&#xff0c;我想是焦虑失落的吧。 01 “降本增效”&#xff0c;HR怒提裁员刀 小默 | 32岁 芯片行业 人力资源 1月份&#xff0c;身处芯片行业H…

额度系统设计

一、额度生命周期额度生效/失效&#xff1a;授信的时候风控返回用户额度&#xff0c;当额度有效期到期之后额度失效&#xff1b;额度预扣/占用/释放&#xff1a; 当客户来提款的时候&#xff0c;只要提款金额小于授信额度(可用额度)时&#xff0c;先预扣&#xff0c;处理完系统…

如何让APP在Google Play中成为特色

Google Play覆盖了 190 多个地区&#xff0c;数十亿的用户&#xff0c;所以开发者都会希望APP在应用商店中获得推荐位。 Google Play 上的精选热门应用类型&#xff1a;热门游戏或应用&#xff0c;畅销应用&#xff0c;安装量增长的应用&#xff0c;产生最多收入的应用。 那么…

Pdfium.Net SDK 4.78.2704 完美Crack/Ptach

不限制时&#xff0c;/不限PDF体积、、、、、// version: 4.78.2704 | file size: 52.7 Mb Pdfium .Net SDK C# PDF 库 从头开始或从一堆扫描图像创建 PDF 编辑、合并、拆分和操作 PDF&#xff0c;提取文本和图像 嵌入独立的 Winforms 或 WPF PDF 查看器 支持&#xff1a;.Net…