js中对象的继承机制本质上是基于对象原型的继承,而不是想java 、c#等是基于类的继承,理解这一点很重要。
还有一点就是,本质上讲,js中只有对象,没有类。我们可以理解为类也是一个对象,可称为类对象。类名通常用构造函数的名称表示,因而类是构造函数的外在表现,但这并不是说类就是构造函数。
类、构造函数、原型:
构造函数是用来初始化新创建的对象,使用关键字new来调用构造函数。使用new调用构造函数会自动创建一个新对象,因此构造函数的本质是只需初始化这个新对象的状态即可。调用构造函数的一个重要特征是,构造函数的prototype属性被用做新对象的原型。这意味着通过同一个构造函数创建的所有对象都继承自同一个相同的对象,因此他们都是同一个类的成员。原型对象是类的唯一标识:当且仅当两个对象继承自同一个原型对象时,它们才是属于同一个类的实例。而初始化对象的状态的构造函数则不能作为类的标识,两个构造函数的prototype属性可能指向同一个原型对象,那么这两个构造函数创建的实例是属于同一个类。
原型对象中通常有一个constructor属性指向构造函数对象,而构造函数对象中会有一个prototype属性指向其原型对象,因而就有:
Person.prototype.constructor ==Person; // => true
Person类
function Person(name,age){ this.name=name; this.age=age; this.eat=function(){ console.log(this.name + "在吃饭"); } /*this.sleep=function(){ console.log("(实例中的):"+this.name+"在睡觉"); }*/ }
new Person() 对象,调用其方法。
var p =new Person("张三",22); //p.sleep(); //如果 实例和原型中存在相同的方法、属性,优先找实例中的,找不到再找到原型中找 Person.prototype.sleep=function(){ //原型对象中的this也是执行新new出来的实例对象 console.log("(原型中的) "+this.name+"在睡觉"); }; p.sleep(); // //如果 实例和原型中存在相同的方法、属性,优先找实例中的,找不到再找到原型中找
道格拉斯原型继承:
//子类继承父类原型 (道格拉斯 原型继承) function inhertPrototype(SubClass,SuperClass){ function T(){}; T.prototype=SuperClass.prototype; var t =new T(); SubClass.prototype=t; SubClass.prototype.constructor=SubClass; }
我们想新建立Student类继承Person类,让Student对象获取父类Person对象的特权属性,并在原型上继承Person对象,
代码如下:
//子类对象 调用父类对象构造函数,获取父类对象的特权属性 function Student(name,age,grade){ Person.call(this,name,age);//对象冒用 this.grade=grade;//成绩 } //调用道格拉斯原型继承 inhertPrototype(Student,Person); var s=new Student("李四",24); s.eat(); s.sleep(); //动态地在Person原型上添加新方法 ,在之前已实例化的Student、Person实例对象中就可调用新方法 Person.prototype.sayHello=function(){ console.log("你好,我是"+this.name+",我的年龄是:"+this.age); }; s.sayHello(); p.sayHello(); console.log("===================="); //在Student原型上可重写(覆盖)sayHello 方法,p对象不受影响,s对象收到影响。 Student.prototype.sayHello=function(){ console.log("hello,我是"+this.name+",我的年龄是:"+this.age); }; s.sayHello(); p.sayHello(); //Studnet原型上扩展自己的方法 ,s对象即可调用之 Student.prototype.study=function(){ console.log(this.name+"在学习"); }; s.study();
一张图说明原型继承(T为临时类,t为T的实例对象):
注:此时t实例即称为了SubClass的原型对象,达到了SubClass类原型继承SuperClass的目的。
Copyright © 叮叮声的奶酪 版权所有
备案号:鄂ICP备17018671号-1