上篇提到构造函数包含一个prototype是实现继承的关键,就是原型链的概念。在JavaScript中当使用构造函数创建一个对象时,如下面的图示(来自<<JavaScript高级程序设计>>):
JavaScript为建构函数生成一个原型(Prototype)指向原型对象,包含了所有实例共享的对象。而原型中也有一个constructor指向建构函数,以起到标识的作用,说明”我是谁”.
建构函数本身也是一个普通函数,只是首字母大写了。
当通过访问实例的属性和方法时:
a.如果实例定义了同名的属性或方法,使用之。
b.否则,尝试调用原型的同名属性或方法。
这里有一个关键的准则:
所有在建构函数中定义的属性和方法,各个实例各自拥有一份。
所有在原型中定义的引用类型属性(基本类型除外)和方法,各个实例将共享使用。
下面是一个包含建构和原型两种方式的对象创建示例:
function Person(name)
{
this.name = name;
}
Person.prototype =
{
friends:["A","B"],
introduceSelf : function()
{
document.write("<p /> My name is "+this.name);
document.write("<p /> My friends are "+this.friends);
}
};
var horky = new Person("Horky");
horky.friends.push("C");
var arthas = new Person("Arthas");
horky.introduceSelf(); //My friends are A,B,C
arthas.introduceSelf(); //My friends are A,B,C
输出的结果是:
My name is Horky
My friends are A,B,C
My name is Arthas
My friends are A,B,C
认识这个特性很重要。一般我们希望类的方法可以重用,而不是各个实例再拥有一份实现,就可以放到原型的定义里面去。而对于子类需要自己定义的属性就可以放到建构函数中去。
既然原型也是一个对象,就可以按需要修改,比如扩展一下类的功能,随时加一个定义就可以了。
在上面代码后加入类似下面的代码:
……
horky.introduceSelf(); //My friends are A,B,C
arthas.introduceSelf(); //My friends are A,B,C
Person.prototype.saySomething = function(text)
{
document.write("<p /> "+this.name+" says:"+text);
}
horky.saySomething("Hello, everyone!");
输出结果就会多一行:
Horky says:Hello, everyone!
理解了原型,我们再看一下继承。继承的要素是继承父类的属性和方法定义,而且属性可以自行更改。本身实例和原型之间就是继承关系的影子,因为访问是从下至上的。所以继承无非是要将子类的prototype变成一个指向父类原型的对象就可以了,如下图:
这就是<<JavaScript高级程序设计>>中所讲的较常用的寄生组合式继承。寄生指的是调用建构函数,组合则指的原型的运用。下面是示例代码:
function inheritPrototype(subType,superType){
var prototype=object(superType.prototype); //创建对象
prototype.constructor=subType; //增强对象
subType.prototype=prototype; //指定对象
}
function SuperType(name){
this.name=name;
this.color=["red","blue","greed"];
}
SuperType.prototype.sayName=function(){
alert(this.name);
}
function SubType(name,age){
SuperType.call(this,name); //呼叫父类的建构函数
this.age=age;
}
inheritPrototype(SubType,SuperType); //将子类设定为继承自父类
SubType.prototype.sayAge=function(){ //增加一个子类方法
alert(this.age);
};
只要掌握前面所提原型的概念,JavaScript中使用很多OO的实现就很好理解了。比如所谓的模块(单件)模式之类的。
*<<JavaScript高级程序设计>>第3版在这段代码下(P173)附的图6-6是属于前段代码的解释,放在这段代码下实在容易让人误解。
分享到:
相关推荐
主要介绍了javascript 对象 与 prototype 原型用法,结合实例形式分析了javascript 对象 与 prototype 原型实现对象创建、继承、拷贝等相关操作技巧,需要的朋友可以参考下
对于javascript原型链,以前都觉得是个很深的东西,一直没有理解很明白,今天看了一些介绍后,发现这张图,表示再没有什么语言能比这张图说得清楚了。 看了这张图后突然对javascript有了质的理解。 javascript的...
一说到prototype很多人可能第一个想到的是著名的prototype.js框架,当然我们今天说的不是它,而是Javascript中的prototype属性,一般都被翻译为“原型”。这是一个比较特殊的属性,Javascript中的继承一般都依赖这...
1. 继承是面向对象编程语言的一个重要特性,比如Java中,通过extend可以实现多继承,但是JavaScript中的继承方式跟JAVA中有很大的区别,JS中通过原型链的方式实现继承。 (1)对象的原型:因为JS中,函数也是对象,...
我们创建的每个函数都有一个 prototype (原型)属性,这个属性是一个指针,指向一个原型对象,而这个原型对象中拥有的属性和方法可以被所以实例共享。 function Person(){ } Person.prototype.name = "Nicholas"; ...
本文实例讲述了JavaScript使用Prototype实现面向对象的方法。分享给大家供大家参考。具体分析如下: prototype 是 Function 对象的一个属性,这个属性指向另一个对象。 这个对象的所有属性和方法,都会被构造函数的...
这一语言功能的本质依赖于 JavaScript 特有的原型链(prototype chain)模式。 所以严格意义上说,JavaScript 是基于原型的面向对象语言。也就是说,每个实例对象都具有一个原型。对象从该原型中继承属性和方法。 1、...
本文实例讲述了javascript原型模式用法。分享给大家供大家参考。具体分析如下: 一般在了解了工厂模式和构造函数模式的弊端之后,就知道为什么需要原型模式了 原型模式i的定义:每个函数都有一个prototype(原型)...
本文实例讲述了JS中prototype的用法。分享给大家供大家参考。具体分析如下: JS中的phototype是JS中比较难理解的一个部分 本文基于下面几个知识点: 1 原型法设计模式 在.Net中可以使用clone()来实现原型法 ...
主要介绍了JS利用prototype给类添加方法操作,结合实例形式分析了javascript使用prototype实现给类添加方法的相关操作技巧,需要的朋友可以参考下
首先来分析构造函数和原型链两种实现继承方式的缺陷: 构造函数(对象冒充)的主要问题是必须使用构造函数方式,且无法继承通过原型定义的方法,这不是最好的选择。不过如果使用原型链,就无法使用带参数的构造函数...
在本章中,我们将分析Prototypejs中关于JavaScript继承的实现。 Prototypejs是最早的JavaScript类库,可以说是JavaScript类库的鼻祖。 我在几年前接触的第一个JavaScript类库就是这位,因此Prototypejs有着广泛的...
本文实例讲述了JavaScript面向对象继承原理与实现方法。分享给大家供大家参考,具体如下: 1、构造函数、原型和实例的关系 构造函数有一个原型属性prototype指向一个原型对象。 原型对象包含一个指向构造函数的指针...
isPrototypeOf 方法 返回一个 Boolean 值,表明对象是否存在与另一对象的原型链中。 italics 方法 将 HTML的 <I> 标识添加到 String 对象中的文本两端。 item 方法 返回集合中的当前项。 join 方法 返回一个由...
本文实例讲述了JavaScript实现多重继承的方法。分享给大家供大家参考,具体如下: 1. 定义一个空的父类构造函数,然后通过prototype的方式为该父类定义属性和方法 2. 定义一个空的子类的构造函数,然后将子类的原型...
prototype [property]是javascript中对象的属性,用来返回对象的原型引用,可以动态的给此添加方法和属性,对象如array,object,或者用户定义的对象,详细请看这里 slice [Function]用原array对象,截取指定部分返回一...
今天遇到关于javascript原型的一道面试题,现分析下: 原题如下: function A(){ } function B(a){ this.a = a; } function C(a){ if(a){ this.a = a; } } A.prototype.a = 1; B.prototype.a = 1; C....
isPrototypeOf 方法 返回一个 Boolean 值,表明对象是否存在与另一对象的原型链中。 italics 方法 将 HTML的 <I> 标识添加到 String 对象中的文本两端。 item 方法 返回集合中的当前项。 join 方法 返回一个由...
Bright-U(WebVR原型)目的声明BrightU 2.0是一款移动VR应用程序,通过以新方式向他们显示相关信息,可以帮助销售人员以交互方式了解粘性产品。描述在实习期间,我和我的团队的任务是为Bright House Networks的中...