资讯专栏INFORMATION COLUMN

js中的Java式继承

SillyMonkey / 2619人阅读

摘要:中有三种不同的对象,三种对象的属性和行为和下方的类似构造函数对象构造函数为的类定义名称,任何添加到这个构造函数对象中的属性都是类字段和类方法。

JavaScript中的Java式继承

区别

Java类似的强类型面向对象语言,类为

实例字段

他们是基于实例的属性或变量,用以保存独立对象的状态

实例方法

他们是类的所有实例所共享的方法,由每个独立的实例调用

类字段

这些属性或者变量是属于类的,而不是属于类的某个实例的

类方法

这些方法是属于类的,而不是属于类的某个实例的

js和Java的不同之处

js的函数是以值的形式出现的,方法和字段没有太大的区别,如果属性值是函数,那么这个属性就定义了一个方法,否则仅仅是一个普通的属性或者字段,用js模拟出Java的这四种类成员类型。js中有三种不同的对象,三种对象的属性和行为和下方的类似

构造函数对象

构造函数为js的类定义名称,任何添加到这个构造函数对象中的属性都是类字段和类方法。(如果属性值是函数的话为类方法)

参考上一篇
原型对象

原型对象的属性被类的所有实例所继承。如果原型对象的属性值是函数,这个函数是作为类的实例方法调用

实例对象

类的每个实例都为一个独立的对象,直接给这个实例定义属性是不会为所有实例对象所共享的,定义在实例上的非函数属性,实际上是实例的字段

js中定义类的方法

先定义一个构造函数并设置初始化实例对象的属性

给构造函数的prototype对象定义实例的方法

给构造函数定义类字段和类属性

实现一个表示复数的类 先讨论try和catch的错误处理机制

首先出现throw会直接暂停执行,之前已经说过了

/*这是一个使用try和catch的示范程序*/
function a() {
  try {
    throw "发生错误";
    return "O(∩_∩)O哈哈~";
  } catch(x) {
    throw "继续发送错误";
  }
}

如果程序没有内容会直接执行try,但是由try必须有catch(仅仅是当程序内容为空的情况下),但是对于其扫尾的finally来说则是不一定的,仅此而已

叮, 又发现一个框架 https://formatjs.io/ 不急慢慢来
一些下方要用到的方法

Math.sqrt 平方根
exec()字符串匹配 https://developer.mozilla.org...
制定一个字符串,进行匹配操作
parseFloat() 函数解析一个字符串参数并返回一个浮点数。

下面是完整的一个js的类的实现

/*
 * Complex.js
 * 这个文件定义了Complex类,是用来描述复数
 * 复数是实数和虚数的和,并且虚数i是-1的平方根
 */

/*
 * 这个构造函数为它创建的每个实例定义了字段r和i
 * 这两个字段分别保存复数的实部和虚部
 * 它们是对象的状态
 */
function Complex(real, imaginary) {
    if (isNaN(real) || isNaN(imaginary))    // 确保两个实参都是数字
        throw new TypeError();    // 如果不都是数字则抛出错误
    this.r = real;    // 复数的实部
    this.i = imaginary;        // 复数的虚部
};

/*
 * 类的实例方法定义为原型对象的函数值属性
 * 这里的定义的方法可以被所有实例进行继承(因为是在其属性上直接添加prototyp,而不是__proto__的,是在其子代直接进行继承的
 * js的实例的方法必须使用this,因为是方法,不是属性,也不是一些帮助运行的属性,再次重复是方法,方法是用来进行对于对象进行处理的
 * 这里是用this来存取实例的字段的
*/

// 当前复数对象加上另外一个复数,并返回一个新的计算和值后的复数对象
Complex.prototype.add = function (that) {
    return new Complex(this.r + that.r, this.i + that.r);
};

// 当前复数乘以另外一个复数,并返回一个新的计算乘积之后的复数对象
Complex.prototype.mul = function (that) {
    return new Complex(this.r * that.r - this.i * that.i, this.r * that.i + this.i * that.r);
};

// 计算复数的模,复数模定义为原点(0,0)到复平面的距离
Complex.prototype.mag = function() {
    return Math.sqrt(this.r * this.r + this.i * this.i);
};

// 复数求负运算
Complex.prototype.neg = function () {
    return new Complex(-this.r, -this.i);
};

// 将复数对象转换为一个字符串
Complex.prototype.neg = function () {
    return "(" + this.r + "," this.i + ")";
};

// 检测当前复数对象是否和另外一个复数值相等
Complex.prototype.equals = function (that) {
    return that != null &&     // 该对象必须有定义,为了防止两个值是空值仍然相等的情况,至于为什么能分行写,是因为没有结束,并且用&&作为语句的连接,使其变为一个语句
    that.constructor == Complex &&     // 比较的另外一个复数必须是Complex的类,否则无法比较
    this.r === that.r && this.i === that.i // 实部必须和虚部相等,一般比较使用严格相等比较运算符,因为严格相等比较运算符比相等比较运算符更加严格,也跟加安全,防止出现undefined或者null的问题
};

/* 类字段(比如常量)和类方法直接定义为构造函数的属性(这里是用来书写一些构造函数的属性的)
 * 需要注意的是,类的方法通常不使用this 这是因为一般js使用类的时候是new,而new的过程是,先创建一个空对象,然后将对象的原型链进行赋值(prototype),然后再将空对象的方法,进行赋值,其中全是赋值,并没有使用其对象的方法,所以一般不使用this
 * 并且,类仅仅是作为一个工厂生产相关的函数,仅此而已。因为只作为生产,而不进行更改,同样也不使用this
 * 这些只是对其参数进行操作。参考上一条
 */

// 这里预定了一些对复数运算的有帮助的类字段
// 这里的类方法通常不使用关键字this
// 他们的命名全是大写,用来表明他们是常量,用来进行替代某些内容
// 在ES5中的这些类字段的属性值为只读
Complex.ZERO = new Complex(0, 0);    // 使用这个常量创建一个新的对象
Complex.ONE = new Complex(1, 0);
Complex.I = new Complex(0, 1);

// 这个类方法将由实例对象的toString方法返回的字符串格式解析为一个Comoplex对象的parse属性
// 即这个类方法是是将字符串进行解析的一个类方法
// 使用try的原因是因为js为单线程的,即使捕获异常,避免线程调用失败(毕竟为单线程的嘛) 部分异常不重要,放置局部影响到全局(降低耦合性) 进行对项目的分层,MVC模式,方便更加‘优雅’的找出错误(*^__^*) 嘻嘻……防止找错误的时候不必要心慌,这是关键(⊙o⊙)
// 或者抛出一个类型错误异常
// 因为这里是另外的处理,和其余不同,所以命名使用_开头,方便进行查找
Complex.parse = function(s) {
    try {    // 假设解析成功
        var m = Complex._format.exec(s);    // 利用正则表达式进行匹配
        return new Complex(parseFloat(m[1]), parseFloat(m[1]));
    } catch(x) {    // 如果解析失败则抛出异常
        throw new TypeError("can"t parse ""+ s""as a complex number.");
    }
};

// 定义类的私有字段,这个字段在Complex.parse()中用到了
// 依旧,命名,下划线前缀表明是类的内部使用的,不属于类的公有api部分,因为公有api部分要使用prototype进行继承
Complex._format = /^{([^,]+), ([^}]+)}&/;

// (^o^)/完成啦~(≧▽≦)/~啦啦啦

文件地址https://github.com/meloveming...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/96258.html

相关文章

  • 面向对象的 JavaScript

    摘要:是完全的面向对象语言,它们通过类的形式组织函数和变量,使之不能脱离对象存在。而在基于原型的面向对象方式中,对象则是依靠构造器利用原型构造出来的。 JavaScript 函数式脚本语言特性以及其看似随意的编写风格,导致长期以来人们对这一门语言的误解,即认为 JavaScript 不是一门面向对象的语言,或者只是部分具备一些面向对象的特征。本文将回归面向对象本意,从对语言感悟的角度阐述为什...

    novo 评论0 收藏0
  • JavaScript继承详解

    摘要:可以通过构造函数和原型的方式模拟实现类的功能。原型式继承与类式继承类式继承是在子类型构造函数的内部调用超类型的构造函数。寄生式继承这种继承方式是把原型式工厂模式结合起来,目的是为了封装创建的过程。 js继承的概念 js里常用的如下两种继承方式: 原型链继承(对象间的继承) 类式继承(构造函数间的继承) 由于js不像java那样是真正面向对象的语言,js是基于对象的,它没有类的概念。...

    Yangyang 评论0 收藏0
  • 浅谈JavaScript的面向对象和它的封装、继承、多态

    摘要:会造成内存浪费的问题构造函数继承声明父类声明子类生成实例组合式继承组合式继承是汲取了两者的优点,既避免了内存浪费,又使得每个实例化的子类互不影响。 写在前面 既然是浅谈,就不会从原理上深度分析,只是帮助我们更好地理解... 面向对象与面向过程 面向对象和面向过程是两种不同的编程思想,刚开始接触编程的时候,我们大都是从面向过程起步的,毕竟像我一样,大家接触的第一门计算机语言大概率都是C语...

    MAX_zuo 评论0 收藏0
  • JS对象(1)重新认识面向对象

    摘要:对象重新认识面向对象面向对象从设计模式上看,对象是计算机抽象现实世界的一种方式。除了字面式声明方式之外,允许通过构造器创建对象。每个构造器实际上是一个函数对象该函数对象含有一个属性用于实现基于原型的继承和共享属性。 title: JS对象(1)重新认识面向对象 date: 2016-10-05 tags: JavaScript 0x00 面向对象 从设计模式上看,对象是...

    superw 评论0 收藏0
  • SegmentFault 技术周刊 Vol.32 - 七夕将至,你的“对象”还好吗?

    摘要:很多情况下,通常一个人类,即创建了一个具体的对象。对象就是数据,对象本身不包含方法。类是相似对象的描述,称为类的定义,是该类对象的蓝图或原型。在中,对象通过对类的实体化形成的对象。一类的对象抽取出来。注意中,对象一定是通过类的实例化来的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 马上就要到七夕了,离年底老妈老爸...

    李昌杰 评论0 收藏0

发表评论

0条评论

SillyMonkey

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<