javascript代码实例教程-javascript继承―prototype属性介绍(2)

发布时间:2019-01-27 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了javascript代码实例教程-javascript继承―prototype属性介绍(2)脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
小宝典致力于为广大程序猿(媛)提供高品质的代码服务,请大家多多光顾小站,小宝典在此谢过。 js里每一个function都有一个PRototyPE属性,而每一个实例都有constructor属性,并且每一个function的prototype都有一个constructor属性,这个属性会指向自身。这会形成一个非常有意思的链式结构。举例如下:

 

function Person(){

    this.name =12;

}

console.LOG(Person.prototype);

console.log(Person.prototype.constructor);//输出Person,指向自身

console.log(Person.prototype.constructor.prototype.constructor);//输出Person,指向自身

/***再看一下这个类的输出,则会出现如下情况**/

function Person(){}

Person.prototype.name = 'xiaoming';

VAR p1 = new Person();

console.log(p1);

输出结果如下:

 

image

 

会把这个实例显示出来,展开如下。p1有一个原型属性,这个属性有一个构造方法Person(),而这个构造方法又有prototype属性,这个属性有constructor方法…

 

image

 

这里主要让我们了解一下prototype是属于类(或者说函数function)的属性,指向这个类的共有属性和方法,而constructor是实例的属性,指向它的构造函数(也可以说是类,js里构造函数和类是一个概念)。

 

通过前面的两篇文章

 

javascript继承—继承的实现原理(1)

 

javascript创建对象的三种模式

 

我们知道用prototype来实现继承可以使子类拥有父类的共有属性和方法,其它两种不行。所以这里主要讨论如何用prototype实现继承。

 

由于采用prototype继承父类的实例在javascript继承—继承的实现原理(1)中已有论述,下面着重介绍用prototype继承实现的几种方式。

 

方案一:

 

直接将父类的prototype属性赋给子类,同时用call继承父类的特权属性,然后再修改子类prototype的constructor

 

复制代码

function Person(name,age){

    this.name = name;

    this.age = age;

}

 

Person.prototype = {

    sayHi:function(){

        alert('hi');

    }

}

 

function Student(name,age,grade){

    Person.call(this,name,age);

    this.grade = grade;

}

 

Student.prototype = Person.prototype; 

//Student.prototype.constructor = Student;

Student.prototype.study = function(){

    alert('study');

}

var p1 = new Person('xiaoming',10);

var s1 = new Student('xiaohong',9,3);

//p1.study();// p1.study is not a function 说明Person的实例没有study方法,即子类的共有方法没有被父类共享

console.log(p1);//Person { name="xiaoming", age=10, sayHi=function()}

console.log(s1);//Student { name="xiaohong", age=9, grade=3, 更多...}

console.log(p1.constructor);//Object() 

console.log(s1.constructor);//Object() 子类父类实例相同都为Object

 

/**

如果在原文中加上Student.prototype.constructor = Student;

console.log(p1.constructor);//Student() 

console.log(s1.constructor);//Student() 子类父类实例相同都为Student

***/

复制代码

这种方案经测试是行不通的,因为不管怎么变,子类和父类的实例都会共有相同的constructor,这种情形下修改子类的共有方法,同时会修改了父类的共有方法,说明此法不通。

 

方案二:

 

将父类的实例赋给子类的原型对象,同时使用call方法使子类继承父类的特权属性。

 

复制代码

function Person(name,age){

    this.name = name;

    this.age = age;

}

 

Person.prototype = {

    constructor:Person,

    sayHi:function(){

        alert('hi');

    }

}

 

function Student(name,age,grade){

    Person.call(this,name,age);

    this.grade = grade;

}

 

Student.prototype = new Person();

Student.prototype.constructor = Student;

Student.prototype.study = function(){

    alert('study');

}

var p1 = new Person('xiaoming',10);

var s1 = new Student('xiaohong',9,3);

//p1.study();// p1.study is not a function 说明Person的实例没有study方法,即子类的共有方法没有被父类共享

console.log(p1);//Person { name="xiaoming", age=10, sayHi=function()}

console.log(s1);//Student { name="xiaohong", age=9, grade=3, 更多...}

console.log(p1.constructor);//Person(name,age) 父类的实例指向仍是父类

console.log(s1.constructor);//Student(name,age,grade) //子类的实例指向仍是子类

复制代码

得到的结果基本符合我们继承的要求,但是这个继承实现方式所继承的是父类实例所有的属性和方法,即实例方法(也可以说是特权方法),每创建一个子类对象都会把父类的特权方法,共有方法都复制一遍,这样代码区会出现大量重复。这时创建子类的实例就相当于javascript创建对象的三种模式 中的第二种构造函数模式。

 

方案三:

 

用prototype实现原型链继承。

 

复制代码

function Person(name,age){

    this.name = name;

    this.age = age;

}

//第一种创建共有方法方式

Person.prototype.sayHi = function(){

    alert('hi');

}

//第二种创建共有方法方式

/*--------------------------------------------------------

Person.prototype = {

    constructor:Person,

    sayHi:function(){

        alert('hi');

    }

}

-------------------------------------------------------*/

 

function Student(name,age,grade){

    Person.call(this,name,age);

    this.grade = grade;

}

 

for(var i in Person.prototype){Student.prototype[i] = Person.prototype[i]}

Student.prototype.study = function(){

    alert('study');

}

var p1 = new Person('xiaoming',10);

var s1 = new Student('xiaohong',9,3);

//p1.study();// p1.study is not a function 说明Person的实例没有study方法,即子类的共有方法没有被父类共享

console.log(p1);//Person { name="xiaoming", age=10, sayHi=function()}

console.log(s1);//Student { name="xiaohong", age=9, grade=3, 更多...}

console.log(p1.constructor);//Person(name,age) 父类的实例指向仍是父类

console.log(s1.constructor);//Student(name,age,grade) //子类的实例指向仍是子类

/*--------------------------------------------------------

第二种方式

console.log(p1.constructor);//Person() 父类的实例指向仍是Person

-------------------------------------------------------*/

复制代码

对于第二种创建共有方法,如果创建的时候不加constructor: Person,得到的父类实例会指向Object,是因为创建共有方法的时候直接将一个包含共有方法的Object对象赋给了父类的prototype属性,将父类原有的constructor属性Person修改为Object。所以会出现这种情形。

 

经过测试,这种继承方式是可行的。使用这种方式继承,可以看到基本实现了子类继承父类的所有属性和方法,并且子类的构造函数仍是子类,父类的构造函数是父类。自认为这是最佳方案。

 

 

觉得可用,就经常来吧! 脚本宝典 欢迎评论哦! js脚本,巧夺天工,精雕玉琢。小宝典献丑了!

脚本宝典总结

以上是脚本宝典为你收集整理的javascript代码实例教程-javascript继承―prototype属性介绍(2)全部内容,希望文章能够帮你解决javascript代码实例教程-javascript继承―prototype属性介绍(2)所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。