JS 超类和子类

此篇由别的大神的博客与《javascript高级程序设计》一书整理而来

原博客地址:https://hyj1254.iteye.com/blog/628555

看到javascript高级程序设计的面向对象章节看到超类与子类这个概念词,不懂上度娘查了才知道是怎么一回事。

说到超类与子类,就不得不提起原型模式,原型对象,原型链与原型链继承了

在原型模式章节中,对于原型模式这样描述:“我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。如果按照字面意思来理解,那么prototype 就是通过调用构造函数而创建的那个对象实例的原型对象”

这一段话表明了:prototype由构造函数Object()创建,所以它本身也是一个Object实例,而任何Object实例都可以从Object.prototype中继承属性;于是prototype就也具有了这种能力;

而对于原型对象,书中描述如下:

“无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。在默认情况下,所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype 属性所在函数的指针

这段话 表明了:函数的prototype属性指向函数的原型对象,而原型对象又会指回创建的函数

(prototype属性以及constructor属性都是浏览器内部生成,外部不可直接访问)

鉴于此种特性,我们将另一个类型的实例赋值给一个函数的原型对象(fun1.prototype=new fun2()),这样原本存在于该实例的属性以及方法也存在于原型对象中了,这样层层递进就构成了原型链。

另一个很重要的信息:基于prototype的继承不仅仅局限于单一的prototype对象,访问沿着一条prototype链逐级向上执行:假设有个Complex实例,访问其中一属性,如果本身找不到,便访问Complex.prototype对象;还找不到即在Object实例中找不到,就接着访问Complex.prototype的上一级--Object.prototype。

这就解释了为什么JS对象都从Object对象中继承了方法:如自定义了Complex类,然后它的每个实例就都能访问toString()方法,因为它的prototype是Object实例,能访问Object.prototype。

  这就是所谓“超类和子类”的核心。拿上例来说,它所表述的是,由于Complex.prototype默认是Object的实例(由Object()初始化),于是Complex便继承了Object(即可以访问Object和Object.prototype的所有属性)。 
    好戏登场了:只要把Complex.prototype的构造函数换成其他的,而不是默认的Object(),那Complex便成为了那个类的子类;这就实现了自己定义的超类和子类关系。当然Complex还是Object的子类,但那是因为那个类最终也是Object的子类。

举个栗子:

1 function Person(name){this.name=name;}
2 Person.prototype.say=function(){alert("hello");};
3 function Man(){}
4 Man.prototype=new Person("Tom");
5
6 var man=new Man();
7 alert(man.name);//Tom,继承了Person实例的属性:name
8 man.say();//hello,继承了Person.prototype的属性:say
9 alert(man.hasOwnProperty(‘name‘));//false,name在Man.prototype中

在上面的栗子中,Man是Person的子类

当然,这样写虽然能达到效果,但可能不符合“标准”,那就换成标准的:

 1 function Person(name){this.name=name;}
 2 Person.prototype.say=function(){alert(this.hasOwnProperty(‘name‘));}
 3 function Man(name){
 4    Person.call(this,name);//多了这一步,实现实例属性的继承,要先明白call的作用 }
 5 Man.prototype=new Person();//继承Person.prototype的属性。
 6 //--------------
 7 var man = new Man("Tom");
 8 alert(man.constructor==Person);//true
 9 Man.prototype.constructor=Man;//将Man的构造函数指回Man
10 alert(man.name);//Tom
11 alert(man.hasOwnProperty(‘name‘));//true,通过call方法,name已经成为man的实例属性。hasOwnProperty判断man本身是否具有name属性。
12 man.say();//true,继承了Person.prototype的属性,this指向man
13 alert(Man.prototype.constructor==Person);//false
14 alert(Man.prototype instanceof Person);//true

总结以上就是:Man是谁的子类就看Man.prototype是由谁的构造函数初始化的。只要把握了这点,继承关系可以随心所欲的构造。

原文地址:https://www.cnblogs.com/xiao-baobao/p/10496431.html

时间: 2024-11-13 06:39:52

JS 超类和子类的相关文章

JS中,子类调用超类函数

概述 JS虽然并不直接具备面向对象的特性,但仍可以通过prototype来模拟面向对象的继承和多态等特性.和大多数面向对象语言(例如C++,Java等)相比,JS来实现面向对象仍稍显繁琐和抽象,需要对JS的prototype模型有深入的理解. 在开发过程中,有时候会遇到这样一个问题:如果在子类中"覆盖"了超类的某个方法,但仍需要在子类方法中调用一次超类方法,这时候应该怎么做?如果是Java,一个简单的super关键字即可解决问题,但如果是JS呢? 解决问题的最基本方法可以是:在子类中,

5.1 类、超类和子类

5.1 类.超类和子类 子类比超类拥有的功能更加丰富. 在本例中,Manager类比超类Employee封装了更多的数据,拥有更多的功能. 在Manager类中,增加了一个用于存储奖金信息的域,以及一个用于设置这个域的方法: class Manager extends Employee { private double bonus; ... public void setBouns(double b) { bonus = b; } } 如果有一个Manager对象,就可以使用setBonus方法

Core Java (十一) Java 继承,类,超类和子类

Core Java (十一) Java 继承,类,超类和子类 标签: javaJavaJAVA 2013-01-22 17:08 1274人阅读 评论(0) 收藏 举报  分类: java(58) 读书笔记(46)  版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 继承关系 两个类之间存在三种关系: 依赖,uses-a,如果一个类的方法操纵另一个对象,我们就说一个类依赖于另一个类. 聚合(关联),has-a,一个对象包含另外一个对象,聚合关系意味着类A的对象包含类B的对象

Java超类引用子类对象的规律

首先,对于JVM实现引用的一个机制是:类实例的引用就是指向一个句柄(handle)的指针,这个句柄就是一堆指针:一个指针指向一块从java堆中为分配出来内存空间:另一个指针指向一张表(实际上这个表格也有两个指针(一个指针指向一个包含了对象的方法表,另外一个指向类对象,表明该对象所属的类型)) 下面举例进行分析:  Student st=new Student();//Student为子类 Person p=st;//Person 为超类 p.sayHello();//该方法在超类和子类中都存在

js中的子类继承父类的方法和属性

上次讲了个简单的继承,这次 咱们讲个稍微复杂点的,那就是让子类继承父类的属性和方法,假设人 (Person)是父类,工人(Worker)是子类,让worker继承person的属性和方法: 父类: function Person(name,age) { this.name=name; this.age=age; } Person.prototype.showName=function() { alert(this.name); } function worker(name,age,job) {

JS于,子类调用父类的函数

概要 JS虽然没有直接有面向对象的特性,但还是能prototype为了模拟面向对象的特性,如继承和多态.而大多数面向对象的语言(例如C++.Java等一下)相比,JS为了实现面向对象还是有点繁琐,抽象.需要对JS的prototype模式有深刻的理解. 在开发过程中,有时候会遇到这样一个问题:假设在子类中"覆盖"了超类的某个方法,但仍须要在子类方法中调用一次超类方法,这时候应该怎么做?假设是Java,一个简单的superkeyword就可以解决这个问题,但假设是JS呢? 解决这个问题的最

JAVA构造函数在超类与子类定义鲁波总结

1.子类无构造函数,超类无构造函数,创建的无参数的对象: 编译通过. 1 class A 2 { 3 4 } 5 6 class B extends A 7 { 8 9 } 10 public class Testeeer 11 { 12 public static void main(String [] args) 13 { 14 B b_01=new B(); 15 } 16 } 2.子类有无参数构造函数,超类无构造函数,创建的无参数的对象: 运行结果: 调用了B的无参构造函数 1 clas

继承——类、超类、子类

http://user.qzone.qq.com/1282179846/blog/1470248763 引入一个简单的例子: //Employee类 import java.util.*; public class Employee { private String name; private double salary; private Date hireday; public Employee(String n,double s,int year,int month,int day) { n

js 关于在子类构造函数中加入call(this)的用意!

先上例子: function Animal(a,b) { this.a = a; this.b = b; } function Dog(c) { //Animal.call(this);//注释<1> } Dog.prototype = new Animal(); Dog.prototype.constructor = Dog; var dog1 = new Dog('tom'); console.log(dog1); var animal = new Animal(); console.lo