dojo中的类

news2024/11/13 23:17:19

使用arcgis api for js 4.*进行地图的web前端开发,就不得不与dojo打交道。dojo是一个框架,自成体系,比如它对类的支持,有自己的一套。众所周知,js不是面向对象语言,没有类这一说,都是用函数来模拟类。

那么dojo里的类是怎么样的呢?

1、定义(声明)类

用declare。

declare(基类,类定义)

第一个参数是基类,单个基类或多个基类组成的数组,如果没有基类,则以null或空数组“[ ]”代替。比如下面:

var A = declare(null, {
  constructor: function(name, age, residence){
    this.name = name;
    this.age = age;
    this.residence = residence;
  }
});

var a = new A("孙悟空",48000,"花果山水帘洞");

类定义,总体上看是一个json。构造函数,各种方法,都是json元素。

constructor,顾名思义,是构造函数。注意name、age、residence并没有声明,直接使用,作为实例的属性。这样不管new多少个A实例,实例之间的属性都不会互相影响。

但我之前不懂,将变量声明在declare之外,new出来的实例,变量居然是共用的。看上去,变量放在declare外部,就相当于全局静态变量。
在这里插入图片描述
注:图中的代码,是dojo比较老旧的版本,所以declare有三个参数。

2、继承

//员工类
define(["dojo/_base/declare", "my/Person"], function(declare, Person){
  return declare(Person, {
    constructor: function(name, age, residence, salary){
      // The "constructor" method is special: the parent class (Person)
      // constructor is called automatically before this one.

      this.salary = salary;
    },

    askForRaise: function(){
      return this.salary * 0.02;
    }
  });
});

//领导类
define(["dojo/_base/declare", 'my/Employee'], function(declare, Employee){
  return declare(Employee, {
    askForRaise: function(){
      return this.salary * 0.25;
    }
  });
});

//使用员工类和领导类
require(["my/Employee", "my/Boss"], function(Employee, Boss){
  var kathryn = new Boss("Kathryn", 26, "Minnesota", 9000),
      matt    = new Employee("Matt", 33, "California", 1000);

  console.log(kathryn.askForRaise(), matt.askForRaise()); // 2250, 20
});

3、类的链式初始化

就是从最老的祖宗开始,一代接一代的初始化。

require(["dojo/_base/declare"], function(declare){
  var A = declare(null, {
    constructor: function(){ console.log("A"); }
  });

  var B = declare(A, {
    constructor: function(){ console.log("B"); }
  });

  var C = declare(B, {
    constructor: function(){ console.log("C"); }
  });

  new C();
});

// prints:
// A
// B
// C

如果想打断这种链式初始化,如:

require(["dojo/_base/declare"], function(declare){
  var A = declare(null, {
    constructor: function(){
      console.log("A");
    }
  });

  var B = declare(A, {
    "-chains-": {//声明链式初始化为手动模式,其实就是打断了链式传播。好滑稽的方法
      constructor: "manual"
    },
    constructor: function(){
      console.log("B");
    }
  });

  var C = declare(B, {
    constructor: function(){
      console.log("C - 1");
      this.inherited(arguments);//显式调用父类初始化,爷爷或更老的祖宗就不必了
      console.log("C - 2");
    }
  });

  var x = new C();
});

// prints:
// C - 1
// B
// C - 2

4、扩展类

如果要扩展一个类,可以用 类.extend(扩展部分定义)。注意扩展部分是扩展,不是完全覆盖。只有重复部分才会被覆盖,原先没有的,则新增到类里。所谓有则改之,无则增加。类修改后,所有的实例都受到影响。

extend返回扩展后的类。

示例如下:

require(["dojo/_base/declare"], function(declare){
  var A = declare(null, {
    m1: function(){
      // ...
    }
  });

  A.extend({
    m1: function(){
      // this method will replace the original method
      // ...
    },

    m2: function(){
      // ...
    }
  });

  var x = new A();
  a.m1();
  a.m2();
});

5、派生类

多说无益,直接看代码

require(["dojo/_base/declare"], function(declare){
  var A = declare(null, {
     m1: function(){},
     s1: "bar"
  });
  var B = declare(null, {
      m2: function(){},
      s2: "foo"
  });
  var C = declare(null, {});
});

对于上述代码,下面2种方法的效果是一样的:
1)方式一

var D1 = A.createSubclass([B, C], {
    m1: function(){},
    d1: 42
});
var d1 = new D1();

2)方式二

var D1 = declare([A, B, C], {
    m1: function(){},
    d1: 42
});
var d1 = new D1();

其中方式一就使用了createSubclass。由A派生,同时继承B和C。等同于同时继承A、B、C。
createSubclass有两个参数,参数一为基类,参数二为注入新类的定义。所谓注入,即有则改之,无则增加,参考 4、扩展类。

createSubclass与extend的区别,在于extend只是对现有类进行扩展,而createSubclass是继承并派生出一个新类。

6、调用父类方法

inherited()

这个方法十分令人费解。它最多有三个参数。

第一个参数是方法名,可选。不指定,调用的是父类的当前方法的同名方法(?)

第二个参数是arguments,是个伪变量,不用声明。据说用于“内省(introspection)”,不知道是什么意思。反正名字不能改把它当作保留字看待。

第三个参数是传递的参数,如果没有指定,第二个参数arguments就发挥作用。但如果为[“true”],则返回父类方法的定义,而不执行。

如果没有父类方法,则返回undefined。

require(["dojo/_base/lang", "dojo/_base/declare"], function(lang, declare){
  var A = declare(null, {
    m1: function(){
      // ...
    },
    m2: function(){
      // ...
    },
    m3: function(){
      // ...
    },
    m4: function(){
      // ...
    },
    m5: function(){
      // ...
    }
  });

  var B = declare(A, {
    m1: function(){
      // simple super call with the same arguments
      this.inherited(arguments);
      // super call with new arguments
      this.inherited(arguments, [1, 2, 3]);
    }
  });

  // extend B using extend()
  B.extend({
    m2: function(){
      // this method is going to be properly annotated =>
      // we can use the same form of this.inherited() as
      // normal methods:
      // simple super call with the same arguments
      this.inherited(arguments);
      // super call with new arguments
      this.inherited(arguments, ["a"]);
    }
  });

  // extend B using lang.extend()
  lang.extend(B, {
    m3: function(){
      // this method is not annotated =>
      // we should supply its name when calling
      // a superclass:
      // simple super call with the same arguments
      this.inherited("m3", arguments);
      // super call with new arguments
      this.inherited("m3", arguments, ["a"]);
    }
  });

  // let's create an instance
  var x = new B();
  x.m1();
  x.m2();
  x.m3();
  x.m4(); // A.m4() is called
  x.m5(); // A.m5() is called

  // add a method on the fly using declare.safeMixin()
  declare.safeMixin(x, {
    m4: function(){
      // this method is going to be properly annotated =>
      // we can use the same form of this.inherited() as
      // normal methods:
      // simple super call with the same arguments
      this.inherited(arguments);
      // super call with new arguments
      this.inherited(arguments, ["a"]);
    }
  });

  // add a method on the fly
  x.m5 = function(){
    // this method is not annotated =>
    // we should supply its name when calling
    // a superclass:
    // simple super call with the same arguments
    this.inherited("m5", arguments);
    // super call with new arguments
    this.inherited("m5", arguments, ["a"]);
  };

  x.m4(); // our instance-specific method is called
  x.m5(); // our instance-specific method is called
});

7、在arcgis api for js中的应用

示例

define([
  "dojo/_base/declare",
  "esri/geometry/support/webMercatorUtils",
  "./WebGlLayer",
], function (declare, webMercatorUtils, WebGlLayer) {
  return declare(null, {
    constructor: function (mapView) {
      this.core = new Core(mapView);
    },
    draw: function (data, options) {
      this.core.load(data, options);
    },
    clear: function () {
      this.core.clear();
    },
  });

  function Core(mapView) {
  	。。。
  }
});

以上仅为dojo类定义及操作的部分内容。dojo只是一个框架,对类的定义和实现自成一家,有些地方十分有趣。因为前端要用到arcgis api for js,依赖dojo,了解即可,不作深究。dojo有关类的完整阐述,见参考文章。

参考文章:
https://dojotoolkit.org/reference-guide/1.9/dojo/_base/declare.html

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

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

相关文章

人工智能轨道交通行业周刊-第25期(2022.11.28-12.4)

本期关键词:液体安检仪、智慧车站、大机作业、动车打温、实时人体姿态估计、图像压缩 1 整理涉及公众号名单 1.1 行业类 RT轨道交通中关村轨道交通产业服务平台人民铁道世界轨道交通资讯网铁路信号技术交流北京铁路轨道交通网上榜铁路视点ITS World轨道交通联盟V…

Java项目:SSM医院挂号预约管理系统

作者主页:源码空间站2022 简介:Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 本项目分为管理员与医生两种角色; 管理员角色包含以下功能: 管理员登录,添加科室,科室增删改查,医生管理,查看预约信息,…

Redis03:Redis基础知识以及数据类型

Redis基础知识以及数据类型基础知识Redis-key基本数据类型String(字符串)三种特殊的数据类型geospatialhyperloglogbitmaps基础知识 redis默认有16个数据库,默认使用的时第0个,可以使用select进行切换数据库 清除当前数据库 清除全部数据库的内容 Red…

Cmake升级与软链接

记录cmake升级版本的记录,主要参考文章:Unbuntu安装Ros后Cmake变成3.10_向日葵骑士Faraday的博客-CSDN博客 cmake升级、更新(ubuntu18.04)_Doctor_Wu_的博客-CSDN博客_cmake升级 设计安装ros后cmake版本出现问题,且卸…

[附源码]Python计算机毕业设计Django基于Java的员工管理系统

项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等等。 环境需要 1.运行环境:最好是python3.7.7,…

Windows 文件共享功能使用方法,局域网多台电脑之间传送文件

设想一下,家里或者公司有多台电脑,连接同一个Wifi,也就是处于同一个局域网中。 在不能使用微信、网盘的文件传输功能的情况下,这多台电脑之间,就只能用U盘传送数据吗? 不。Windows系统中已经提供了文件共享…

ZMQ之克隆模式的可靠性

克隆服务器的可靠性 克隆模型1至5相对比较简单,下面我们会探讨一个非常复杂的模型。可以发现,为了构建可靠的消息队列,我们需要花费非常多的精力。所以我们经常会问:有必要这么做吗?如果说你能够接受可靠性不够高的、或…

Docker三大核心概念(镜像、容器和仓库)与虚拟化

目录 1. Docker是什么 2. Docker与虚拟化 3. Docker虚拟化的好处 4. Docker核心概念 4.1.镜像 4.2.容器 4.3.仓库 5. CentOS7 安装docker(在线方式) 5.1.内核版本信息检查 5.2 卸载可能存在的旧版本 5.3 安装必要的系统工具 5.4 添加docker-ce安装源 5.5 更新yum缓存 5.…

web前端期末大作业:个人网站设计——响应式个人小站网站HTML+CSS+JavaScript

🎉精彩专栏推荐👇🏻👇🏻👇🏻 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业…

STC 51单片机54——气压水压计HX710B 串口显示均值滤波+滑窗滤波

//气压模块为红色模块,传感器型号未知,其信号放大器型号为HX710B // STC15W408AS 11.0592MHz 波特率9600,串口输出大气压强值 // STC15W408AS没有定时器1,所以用定时器2做波特率发生器 // 采用电脑USB供电会有很大的干扰&#xff…

Unity工具 - 工具聚合页(UEWindow)

随着项目工程的推进,开发者们会根据工作内容的需要在Unity内开发众多的工具。随着工具的增多,Unity 的Menu菜单也会逐渐臃肿,过于分散,工具代码也难以查找。在此问题的基础上,开发了工具聚合页(UEWindow) 这一功能来管…

R绘图案例|基于分面的面积图

简介 最近参加一个统计建模的比赛。模型建模后,需要展示不同模型的性能指标,数据如下所示: 其中,第 1 列是不同样本,共376条。第 2-4 列是随机森林得到的结果,第 5-7 列是XGBoost的结果。一共使用了三种评…

数字验证学习笔记——UVM学习3 核心基类

一、核心基类 UVM世界中的类最初都是从一个uvm_void根类(root class)继承来的,而实际上这个类并没有成员变量和方法。 uvm_void只是一个虚类(virtual class),还在等待将来继承于它的子类去开垦。在继承与u…

适合新手的Pytorch的中文文档

🔎大家好,我是Sonhhxg_柒,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎 📝个人主页-Sonhhxg_柒的博客_CSDN博客 📃 🎁欢迎各位→点赞…

牛客练习赛106

牛客练习赛106 C D 脑筋急转弯的构造题 E 染色法判断二分图 结论,这个图是二分图说明不存在奇环 设左边是x,右边是y 则有xyn,xyn, xyn,且x∗y>边数n∗(n−1)/2−mx*y>边数n*(n-1)/2-m x∗y>边数n∗(n−1)/2−m 也就是说左式最大是n∗n/4(xn/…

【1774. 最接近目标价格的甜点成本】

来源:力扣(LeetCode) 描述: 你打算做甜点,现在需要购买配料。目前共有 n 种冰激凌基料和 m 种配料可供选购。而制作甜点需要遵循以下几条规则: 必须选择 一种 冰激凌基料。可以添加 一种或多种 配料&…

[附源码]计算机毕业设计ssm校园一卡通服务平台

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

Apache+PHP8+MYSQL的配置(目前最新版本)

已有很多年没有WEB开发了,本机都没了测试的服务环境,前几天GO语言的一个测试用例需要用到WEB,于是快速搭建一个Apche环境,也顺便将PHP和MYSQL的环境也配置好,贴出来方便自己和他人,临时需要的时候就更快了&…

机器人控制算法八之路径规划算法:RRT、RRT-Connect、Dynamic-Domain RRTs*

机器人控制算法八之路径规划算法:RRT、RRT-Connect、Dynamic-Domain RRTs* 本文主要介绍基于RRT快速搜索随机树的路径规划算法及其改进,主要参考以下论文: 1.1998 Rapidly-exploring random trees: A new tool for path planning2.IEEE2000 R…

[附源码]计算机毕业设计基于springboot的家政服务平台

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…