JS 超类和子类

时间: 2019-03-09阅读: 1214标签: js知识

看到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是由谁的构造函数初始化的。只要把握了这点,继承关系可以随心所欲的构造。


站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

链接: http://www.fly63.com/article/detial/2289

原生js实现控制函数执行次数/频率

在开发中,遇到需求如下:当函数function fn(){//...}执行的次数超过设定值后,将执行另一个函数fn2。实现方式如下

JavaScript中“javascript:void(0) ”是什么意思

expression 是一个要计算的 Javascript 标准的表达式。表达式外侧的圆括号是可选的,鉴于规范化,以及养成好习惯,建议写上去。当我们使用 void 操作符指定超级链接时,表达式会被计算但是不会在当前文档处装入任何内容。

js浮点数精度丢失问题_如何解决js中浮点数计算不精准?

理解javascript中浮点数计算不精准的原因,如何解决浮点数的四则运算(加减乘除)。js中除了toFixed方法以外的实现方法总汇

手写JavaScript中的bind方法

bind方法返回的是一个绑定this后的函数,并且该函数并没有执行,需要手动去调用。(从这一点看bind函数就是一个高阶函数,而且和call,apply方法有区别)。bind方法可以绑定this,传递参数。注意,这个参数可以分多次传递。

classList的使用,原生js对class的添加,删除,修改等方法的总结,以及兼容操作

classList是一个DOMTokenList的对象,用于在对元素的添加,删除,以及判断是否存在等操作。以及如何兼容操作

深入理解Javascript中apply、call、bind方法的总结。

apply 、 call 、bind 三者都是用来改变函数的this对象的指向的;第一个参数都是this要指向的对象,也就是想指定的上下文;都可以利用后续参数传参;bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。

js中delete关键字

delete关键字的作用:删除对象的属性 语法:delete 对象.属性、可以删除没有使用var关键字声明的全局变量(直接定义在window上面的属性)、删除数组元素、不能删除内置对象的属性、不能直接删除从原型上继承的属性

js中bool值转换以及逻辑运算&&、||、 !!的使用

js作为一门弱类型语言,导致几乎所有数据都能转换为bool的类型,js转换 规则 。了解转换规则目的掌握逻辑运算符&&、||、 !!的使用

js实现获取手机相册并上传

当初有很多人说使用form方法将文件封装来上传,可是因为要照顾到从相机中选择图片,所以一直没有去做。 后来看到了Uploader的方法来传文件,感觉自己找到了 。是使用plus.uploader来完成的

原生js获取当前周数

通过原生Js根据日期获取对应日期的周数,例如今天是2018-01-01那么获取该日期在这一年的周数就为1,有需要的朋友可以参考下。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!