JavaScript核心-继承-原型链

继承是面向对象的编程的一大特性,很多OO语言都支持两种继承方式:接口继承和实现继承。在ECMAScript中,由于函数没有签名,所以无法实现接口继承,只有实现继承。

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

简单回顾一下构造函数、原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而对象的每个实例都有一个指向原型对象的内部指针。

再回顾一下原型对象的用途:用途是包含可以由特定类型的所有实例共享的属性和方法。

原型对象也是一个简单的对象,如果我们让一个原型对象等于另一个类型的实例,也就是说可以让一个原型对象的原型是一个非null的引用,那么此时的原型对象将包含一个指向另一个原型的指针。加入另一个原型又是另一类型的实例,那上述关系依然成立,如此层层递进,就构成了原型链。

总的来说,原型链就是用来实现继承和共享属性的有限对象链。

当我们读取一个实例的属性时,首先会在实例中搜索该属性。如果没有找到该属性,就会在实例的原型中继续搜索该属性。当我们利用了原型链来实现继承时,如果在实例的原型中还没找到该属性,就会在原型的原型中继续寻找,并以此类推,遍历整个原型链。如果遍历了整个原型链还是没找到这个属性的话,就返回undefined值。

因为所有的引用类型都默认继承自Object,所有默认原型都包含一个内部指针,指向Object.Prototype。这也是所有自定义类型都会继承toString(),valueOf()等默认方法的根本原因。

使用原型链来继承会存在以下两个问题:

1.包含引用类型值的原型属性会被所有的实例所共享。这也是我们一般在构造函数中,而不是原型中定义属性的原因。在通过原型来实现继承时,原型实际上会变成另一个类型的一个实例,于是这个实例的属性也就变成了现在原型的属性了。

2.在构造子类型的实例时,不能像超类型的构造函数中传递参数。

解决以上问题的一个方法就是采用组合继承,就是将原型链和借用构造函数的技术组合到一起的一种继承模式。

思路就是使用原型链实现对原型属性和方法(主要是方法)的继承,而通过借用构造函数来实现对实例属性的继承。下面是例子:

function SuperType(name){
	this.name = name;
	this.colors = ["red","yellow"];
}

SuperType.prototype.sayName = function(){
	alert(this.name);
};

function SubType(name,age){
	//借用父类的构造函数,这样SubType的实例中就有了name和colors这两个实例属性,这两个属性就是每个实例独有的了
	<span style="color:#FF0000;">SuperType.call(this,name);</span>
	this.age = age;
}

//继承方法
SubType.prototype = new SuperType();
//这是把SubType的constructor属性改回来,创建SubType实例时调用SubType的构造函数
<span style="color:#FF0000;">SubType.prototype.constructor = SubType;</span>

//在SubType的新原型上添加一个方法
SubType.prototype.sayAge = function(){
	alert(this.age);
};

var instance1 = new SubType("zhu",24);
instance1.colors.push("black");
alert(instance1.colors);  //red,yellow black
instance1.sayName();  //zhu
instance1.sayAge(); 	//24

var instance2 = new SubType("li",23);
instance2.colors.push("blue");
alert(instance2.colors);  //red,yellow blue
instance2.sayName();  //li
instance2.sayAge(); 	//23

上面的代码实例化了两个SubType的实例instance1和instance2,它们既拥有了自己的是、属性,包括colors,同时也有了相同的方法sayName()。

这种组合继承避免了原型链和借用构造函数的确定,融合了其优点,也是JavaScript中最常用的一种继承模式。可以作为模板掌握。

时间: 2024-08-06 16:00:38

JavaScript核心-继承-原型链的相关文章

Javascript 组合继承 原型链继承 寄生继承

Javascript继承通常有三种方式. 第一种:组合式继承: function SuperType(name) { this.name = name; this.colors = ["red", "blue", "green"]; } SuperType.prototype.sayName = function() { console.log(this.name); }; function SubType(name, age) { //通过ca

对Javascript 类、原型链、继承的理解

一.序言 ??和其他面向对象的语言(如Java)不同,Javascript语言对类的实现和继承的实现没有标准的定义,而是将这些交给了程序员,让程序员更加灵活地(当然刚开始也更加头疼)去定义类,实现继承.(以下不讨论ES6中利用class.extends关键字来实现类和继承:实质上,ES6中的class.extends关键字是利用语法糖实现的) Javascript灵活到甚至可以实现接口的封装(类似Java中的Interface和implements). 二.类的实现 1.我对类的理解 ??首先,

图解JavaScript中的原型链

转自:http://www.jianshu.com/p/a81692ad5b5d typeof obj 和 obj instanceof Type 在JavaScript中,我们经常用typeof obj和obj instanceof Type来识别类型,那么两者的区别在哪?先来看两段代码 <!--typeof obj的方式判断--> <script>    var str = "toby";    console.log(typeof str);// stri

JavaScript继承-原型链继承

//原型链继承 function SuperType(){ this.name = 'super'; this.girlFriends = ["xiaoli","xiaowang"]; } SuperType.prototype.sayName = function(){ console.log(this.name); } function SubType(){ this.age = 20; } //创建SuperType的实例赋给SubType的原型 //实现继承

JS面向对象之继承——原型链

原型对象 每个javascript对象都有一个原型对象,这个对象在不同的解释器下的实现不同.比如在firefox下,每个对象都有一个隐藏的__proto__属性,这个属性就是“原型对象”的引用. 原型链 由于原型对象本身也是对象,根据上边的定义,它也有自己的原型,而它自己的原型对象又可以有自己的原型,这样就组成了一条链,这个就是原型链,JavaScritp引擎在访问对象的属性时,如果在对象本身中没有找到,则会去原型链中查找,如果找到,直接返回值,如果整个链都遍历且没有找到属性,则返回undefi

javaScript里的原型链

原型对象也是普通的对象,是对象一个自带隐式的__proto__属性,原型也有可能有自己的原型,如果一个原型对象的原型不为null的话,我们就称之为原型链.原型链是由一些用来继承和共享属性的对象组成的(有限的)对象链. 原型对象中的属性可以被多个实例共享.原型对象存在于构造函数的属性(prototype)中,prototype的值是一个Object类型数据(对象). JavaScript的数据对象有哪些属性值呢,举几个简单的栗子: writable:这个属性的值是否可以改: configurabl

夺命雷公狗---javascript NO:28 原型链

1.原型对象 在JavaScript中,每个构造器在加载后都会自动生成一个对象,我们把这个对象就称之为原型对象. 2.构造器与原型对象的关系 Person构造器与Person原型对象在内存中表现为相互独立,互不影响.但是在Person构造器中存在一个prototype属性指向Person原型对象,同时在Person原型对象中也存在一个属性指向Person构造器. 3.原型对象的作用 当我们在Person构造器的实例对象中引用一个不存在的属性或方法,系统会自动到Person构造器的原型对象中去寻找

Javascript中的原型链

说到原型链,首先得说一下对象. 在javascript中我们经常说"一切皆为对象",而对象又是属性的集合,但并不是所有的类型都是对象,undefined, number, string, boolean都属于简单的值类型,不是对象.我们所说的可以作为对象的有:数组.函数.对象.Null.New Number(). 所以函数是一种对象,但是一切对象又是函数创建的,有人可能会说不对啊,例如下面这种的,obj是对象,但是并没有函数啊. var obj = { a: 10, b: 20 };

JavaScript进阶之原型链

对象 1 function f1(){ 2 }; 3 typeof f1 //"function"函数对象 4 5 6 var o1 = new f1(); 7 typeof o1 //"object"普通对象 8 9 var o2 = {}; 10 typeof o2 //"object"普通对象 JavaScript中将对象分为普通对象和函数对象. 使用函数对象可以创建普通对象,普通对象没法创建函数对象. 凡是通过new Function创建