此篇由别的大神的博客与《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. [批处理]守护NodeJS进程

    背景: 日常进行CI过程中,使用NodeJs方式:GIT更新->检测是否需要编译->调用IncrediBuilder编译->读取编译日志判断是否通过->调用7z打包 问题: 持 ...

  2. Java中日期格式(String、Date、Calendar)的相互转换

    package day20190318; import java.text.ParseException; import java.text.SimpleDateFormat; import java ...

  3. 升级python2.7, 实现python2.7与python3并存

    由于用到twilio模块, 所以需要升级一下python2, 但是又不想舍弃python2, 于是实现了简单的方法 python 先扔一块依赖 yum install zlib-devel bzip2 ...

  4. opencv学习之路(41)、人脸识别

    一.人脸检测并采集个人图像 //take_photo.cpp #include<opencv2/opencv.hpp> using namespace cv; using namespac ...

  5. C#中的反射解析及使用(转)

    原文:https://cloud.tencent.com/developer/article/1129356 1.对C#反射机制的理解 2.概念理解后,必须找到方法去完成,给出管理的主要语法 3.最终 ...

  6. Jenkins学习

    1.jenkins启动卡在密码初始化处不动的情况,参照: https://blog.csdn.net/lylload/article/details/82754101 https://blog.csd ...

  7. spring事务的7种传播行为

    https://blog.csdn.net/weixin_39625809/article/details/80707695 一般用于并发,分布式锁.复杂业务情况

  8. 在微信小程序中将获取到的经纬度(经度纬度)转地址(地名)

    var QQMapWX = require('qqmap-wx-jssdk') var qqmapsdk = new QQMapWX({ key: '填写你的key' // 必填 }) wx.getL ...

  9. Java 学习笔记- classpath classpath*

    转自:https://blog.csdn.net/javaloveiphone/article/details/51994268 1.src不是classpath, WEB-INF/classes,l ...

  10. thinkphp3.2升级至thinkphp5.0.24

    view文件 修改文件名 把tp3.2.3\app\module\view文件夹下所有文件夹拷贝至tp5\app\module\view 打开cmd命令窗口,cd至view文件夹下,执行dir /b ...