此篇由别的大神的博客与《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的子类。

举个栗子:

 function Person(name){this.name=name;}
Person.prototype.say=function(){alert("hello");};
function Man(){}
Man.prototype=new Person("Tom"); var man=new Man();
alert(man.name);//Tom,继承了Person实例的属性:name
man.say();//hello,继承了Person.prototype的属性:say
alert(man.hasOwnProperty('name'));//false,name在Man.prototype中

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

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

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

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

JS 超类和子类的更多相关文章

  1. 窗口 超类化 子类化 HOOK

    body { font-family: Bitstream Vera Sans Mono; font-size: 11pt; line-height: 1.5; } html, body { colo ...

  2. JavaScript 超类与子类 继承

    //超类和子类 继承的实现 function R(w, h) { var date = new Date(); this.width = w; this.height = h; this.create ...

  3. Java核心技术第五章——1.类、超类、子类(2)

    继上一篇Java核心技术第五章——1.类.超类.子类(1) 6.重载解析 假如调用ClassName.Method(args) 1.编译器列出类ClassName所有名为Method的方法. 2.编译 ...

  4. Java核心技术第五章——1.类、超类、子类(1)

    1.定义子类: 关键字extends表明正在构造的新类派生与一个已存在的类.已存在的类称为超类.基类或父类:新类称为子类.派生类或孩子类.超类和子类是Java程序员最常用的两个术语(emmm~~我觉得 ...

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

    1.子类无构造函数,超类无构造函数,创建的无参数的对象: 编译通过. class A { } class B extends A { } public class Testeeer { public ...

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

    Core Java (十一) Java 继承,类,超类和子类 标签: javaJavaJAVA 2013-01-22 17:08 1274人阅读 评论(0) 收藏 举报  分类: java(58) 读 ...

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

    概要 JS虽然没有直接有面向对象的特性,但还是能prototype为了模拟面向对象的特性,如继承和多态.而大多数面向对象的语言(例如C++.Java等一下)相比,JS为了实现面向对象还是有点繁琐,抽象 ...

  8. 窗口的子类化与超类化——子类化是窗口实例级别的,超类化是在窗口类(WNDCLASS)级别的

    1. 子类化 理论:子类化是这样一种技术,它允许一个应用程序截获发往另一个窗口的消息.一个应用程序通过截获属于另一个窗口的消息,从而实现增加.监视或者修改那个窗口的缺省行为.子类化是用来改变或者扩展一 ...

  9. java中构造方法和方法super/this超类与子类中初始化顺序

    java中构造方法和方法全面解析 我相信大多说人都对构造方法.方法不陌生,而且很了解,但我也相信有很多像我这样的没有一个很好很清晰很全面的认识,今天就把它整理如下,希望能给大家带来点方便与帮助,也希望 ...

随机推荐

  1. 佳佳的Fibonacci

    #include<cstdio> #include<cstring> #include<iostream> #include<cmath> #inclu ...

  2. cookiejar

    referer:https://www.cnblogs.com/why957/p/9297779.html文章介绍了四种模拟登陆方法 yield Request()可以将一个新的请求返回给爬虫执行 在 ...

  3. 菜鸟redis初学

    该随笔为本人自学redis所遇到的错误,写这些初衷完全是为了避免以后犯相同的错误,如果对别人有帮助,那就相互促进. 在Java中使用redis,首先你的Jdk要能运行,如果没配置好,网上有很多jdk环 ...

  4. IP通信基础学习第四周(下)

    选择子网掩码时,不总是使用整个八位作为屏蔽位. 在每个子网中,子网掩码是相同的. 在划分子网的情况下,判断两台主机是不是在同一子网中,需看它们的网络号与子网地址是不是相同的. 变长子网掩码VLSM,无 ...

  5. FREERTOS学习笔记

    2012-02-25 21:43:40 为提升自己对实时操作系统(RTOS)的认识,我学习了freeRTOS. 理解了OS任务的状态.优先级的概念.信号量的概念.互斥的概念.队列.内存管理.这都是和R ...

  6. SpringBoot+Thymeleaf问题

    springboot在controller返回数据到thymeleaf报404 用springboot做一个例子,访问controller可以返回数据,但是到thymeleaf却报404, 检查发现路 ...

  7. java线程学习之yield方法

    yield方法是暂停当前正在执行的线程对象,并执行其他线程. 这是一个静态方法,一旦执行,它会使当前线程让出CPU.让出的cpu并不代表当前线程不执行了.当前线程让出CPU后,还会CPU资源的争夺,但 ...

  8. Vue入门:Vue项目创建及启动

    1. 创建Vue项目存放地址 用于存放Vue项目,找个自己处理方便的地方.本人地址:D:\Program Files\Workspace\Vue 2. 创建项目 进入cmd窗口 进入项目存放地址 执行 ...

  9. 20190410Linux中磁盘管理及LVM(week2day1)

    Linux磁盘管理及LVM讲解(week2_day2)   硬盘接口 从整体的角度上,硬盘接口分为IDE.SATA.SCSI和SAS四种,IDE接口硬盘多用于家用产品中,也部分应用于服务器,SCSI接 ...

  10. 用phantomjs进行web界面自动化测试的几个注意点

    貌似我以前说过不少界面自动化测试的坏话,哈哈.最近接触了phantomjs,发现用它进行web界面测试也挺有意思的,下面举几个我使用过程中发现的注意点. 1.需要指定phantomjs位置,否则使用时 ...