javascript对象继承

实现继承主要是依靠原型链来实现的

1、原型链

基本思想就是利用原型让一个引用类型继承另一个引用类型的属性和方法

 1 function Parent(){
 2     this.surname = "li";
 3 }
 4 Parent.prototype.getSurname = function(){
 5     return this.surname;
 6 }
 7 function Child(){
 8     this.name = "kai wen";
 9 }
10 Child.prototype = new Parent();
11 Child.prototype.getName = function(){//继承之后再添加
12     return this.name;
13 }
14 var child = new Child();
15 alert(child.getSurname())
16 alert(child.getName())

分别定义了Partent和Child两个类型,Child继承了Partent,继承是通过创建Partent实例并将其赋给Child.prototype实现的,实现的本质是重写原型对象,随后又给原型添加的新的方法,若这里先添加新的方法,再继承Partent,由于原型被重写,添加的方法就无效

 1
 2 function Parent(){
 3     this.surname = "li";
 4 }
 5 Parent.prototype.getSurname = function(){
 6     return this.surname;
 7 }
 8 function Child(){
 9     this.name = "kai wen";
10 }
11
12 Child.prototype = new Parent();
13
14 Child.prototype = {
15     getName:function(){
16         return this.name;
17     }
18 }
19 var child = new Child();
20 alert(child.getSurname())
通过原型链实现继承时,不能使用对象字面量方法创建原型,这样做会重写原型链,Partent的实例赋值给Child原型,紧接着又将原型替换成对象字面量,导致现在的Child原型是一个Object实例,而非Partent实例,因此Partent与Child之间已经没有关系
原型链虽然很强大,但是也存在问题:
1、包含引用类型值得原型会被所有实例共享,通过原型来实现继承时,原型实际上变成另一个类型的实例,于是实例属性也就变成了原型属性
2、在创建子类型实例时,不能向超类型的构造函数中传递参数

2、借用构造函数

基本思想是在子类型构造函数的内部调用吵类型构造函数
 1 function Parent(){
 2     this.color = ["red","blur"];
 3 }
 4 function Child(){
 5     Parent.call(this)
 6 }
 7 var child1 = new Child();
 8 child1.color.push("black");
 9 alert(child1.color)
10 var child2 = new Child();
11 alert(child2.color)
这样每个新创建的Child实例都会有自己的color属性副本
该方法黑可以在子类型构造函数中向超类型构造函数传递参数
 1 function Parent(surname){
 2     this.surname = surname;
 3 }
 4 function Child(){
 5     Parent.call(this,"Li")
 6     this.name = "kai wen";
 7 }
 8 var child = new Child();
 9 alert(child.surname)
10 alert(child.name)
但是借用构造函数方法,也存在缺点,方法都在构造函数中定义,函数复用性无从谈起,而且在超类中定义的方法,对于子类而言是不可见的

3、组合继承

将原型链与借用构造函数组合到一块,基本思想是使用原型链实现对原型属性和方法的继承,而通过借用构造函数实现对实例属性的继承
 1 function Parent(surname){
 2     this.surname = surname;
 3     this.color = ["red","blue"]
 4 }
 5 Parent.prototype.saySurname = function(){
 6     alert(this.surname)
 7 }
 8 function Child(surname,name){
 9     //继承属性
10     Parent.call(this,surname)
11     this.name = name;
12 }
13 //继承方法
14 Child.prototype = new Parent();
15 Child.prototype.constructor = Child;
16 Child.prototype.sayName = function(){
17     alert(this.name);
18 }
19
20 var child1 = new Child("li","Kai wen");
21 child1.color.push("black");
22 alert(child1.color)
23 child1.saySurname()
24 child1.sayName()
25 var child2 = new Child("wang","fangfang");
26 alert(child2.color)
27 child2.saySurname()
28 child2.sayName()

4、原型式继承

基本思想是借助原型可以基于已有的对象创建新对象,同时还不必因此创建自定义类型

 1 function object(o){
 2     function F(){}
 3     F.prototype = o;
 4     return new F()
 5 }
 6 var Parent = {
 7     surname: "li",
 8     color: ["red","blue"]
 9 }
10 var child1 = object(Parent);
11 child1.color.push("black");
12 var child2 = object(Parent);
13 child2.surname = "wang";
14 child2.color.push("yellow");
15 alert(child1.surname)
16 alert(child1.color)
17 alert(child2.surname)
18 alert(child2.color)

原型式继承要求必须有一个对象可以作为另一个对象的基础,包含引用类型值得属性始终都会共享相应的值

5、寄生式继承

创建一个仅用于封装继承过程的函数

 1 function object(o){
 2     function F(){}
 3     F.prototype = o;
 4     return new F()
 5 }
 6 function createAnother(p){
 7     var clone = object(p);
 8     clone.sayHi = function(){
 9         alert("hi");
10     }
11     return clone;
12 }
13 var Parent = {
14     surname: "li",
15     color: ["red","blue"]
16 }
17 var child = createAnother(Parent);
18 child.sayHi()

缺点是做不到函数复用而降低效率

6、寄生组合式继承

通过借用构造函数来继承属性,通过原型链的混成形式来继承方法,基本思路是不必为了指定子类型的原型而调用超类型的构造函数,只需要超类型原型的副本而已,本质上就是使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型

 1 function object(o){
 2     function F(){}
 3     F.prototype = o;
 4     return new F()
 5 }
 6 function inheritPrototype(child,parent){
 7     //创建超类型原型的副本
 8     var prototype = object(parent.prototype);
 9     prototype.constructor = child;
10     child.prototype = prototype;
11 }
12 var Parent = {
13     surname: "li",
14     color: ["red","blue"]
15 }
16 Parent.prototype.saySurname = function(){
17     alert(this.surname)
18 }
19 function Child(surname,name){
20     Parent.call(this,surname);
21     this.name = name;
22 }
23 inheritPrototype(Child,Parent);
24 Child.prototype.sayName = function(){
25     alert(this.name)
26 }

只调用了一次Parent构造函数,避免了在Child.prototype上创建不必要的多余的属性,同时原型链不变

时间: 2024-10-25 06:24:11

javascript对象继承的相关文章

Javascript对象----继承

Javascript对象具有"自有属性",也有一些属性是从原型对象继承而来的.为了更好地理解这种继承,必须更深入地了解属性访问的细节. 假设要查询对象o的属性x,如果o中不存在x,那么将会在o的原型对象中查询属性x.如果原型对象中也没有x,但这个原型对象也有原型,那么会继续在这个原型对象的原型上执行查询,直到找到X或者查找到一个原型是null的对象位置.可以看到,对象的原型属性构成了一个"链",通过这个"链"可以实现属性的继承. var o = 

JavaScript 对象继承

原型继承: 这种原型继承的特点:既继承了父类的模板,又继承了父类的原型对象.优点是继承了父类的模板,    又继承了父类的原型对象,缺点就是父类实例传参,不是子类实例化传参,不符合常规语言的写法. 1 function animal(footnum,eyescolor,feathercolor){ //夫类 2 this.foot = footnum; 3 this.eyes = eyescolor; 4 this.feather = feathercolor; 5 } 6 animal.pro

JavaScript对象继承的方法

写这个话题单纯是给自己做笔记了,不然老忘记. 第一种方法:     function fn1(x) {         this.x = x;     }     function fn2(x, y) {         this.tmpObj = fn1;         this.tmpObj(x);         delete this.tmpObj;         this.y = y;     } 第二种方法:call()或apply()     function fn1(x) {

JavaScript对象 创建对象 继承

创建对象  --以下内容来自JavaScript高级程序设计 工厂模式 用函数来封装以特定接口创建对象的细节. function createPerson(name, age, job){ var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName = function(){ alert(this.name); }; return o; } var person1 = createPerson("Nichola

JavaScript大杂烩4 - 理解JavaScript对象的继承机制

面向对象之继承 JavaScript是单根的面向对象语言,它只有单一的根Object,所有的其他对象都是直接或者间接的从Object对象继承(没有指定父类的对象,都被认为是从Object继承的). 在前面我们讨论了面向对象的封装性,在最后的地方也谈到了JavaScript的继承是通过原型和原型链实现的,下面我们就详细的展开这个问题:JavaScript到底是如何实现继承的? 继承的本质 继承的本质是重用,从语法上来讲,继承就是"D是B"的描述,其中B是基类,描述共性,D是子类,描述特性

JavaScript 对象的原型扩展(JS面向对象中的继承)

<script type="text/javascript"> function person(name, age) { this._name = name; this._age = age; var _self = this; this.say = function() { console.log(this._name + '-' + this._age); setTimeout(function() { console.log(_self._name); }, 2000

javascript对象创建及原型继承的研究

今天总结了下javascript关于原型继承和对象创建方面的东西,因为javascript的原型继承在使用传统面向对象语言开发的同学看来比较怪异,原型继承确实比传统OOP语言的继承理解和运用起来困难一些,当然个人觉得传统OOP的继承相对比较简单,因为中规中矩. 下面逐个的用示例说明javascript中对象创建方式,专业一点叫什么模式,主要有直接单个创建:工厂模式:提出方法类函数公用方式:构造函数模式:构造函数+原型方式:使用原型本质的方式构建(这种受过李站的<悟透javascript>一书的

JavaScript 的对象继承方式,有几种写法?

JavaScript 的对象继承方式,有几种写法? 一.对象冒充 其原理如下:构造函数使用 this 关键字给所有属性和方法赋值(即采用类声明的构造函数方式).因为构造函数只是一个函数,所以可使 Parent 构造函数 成为 Children 的方法,然后调用它.Children 就会收到 Parent 的构造函数中定义的属性和方法.例如,用下面的方式定义 Parent 和 Children: 原理:就是把 Parent 构造函数放到 Children 构造函数里面执行一次.那为什么不直接执行,

javaScript 工作必知(七) 对象继承

对象继承inherit var o = { r: 1 }; var c = function f() { }; c.prototype = o; c.r = 3; alert(o.r);//被继承的属性值未发生改变. alert(c.r);//c中r覆盖了o中的属性.     如何调用o中的r属性呢. var o = { r: 1 }; var c = function f() { }; c.prototype = o; alert(o.r);//1 被继承的属性值未发生改变. alert(c.