`
holdbelief
  • 浏览: 707578 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论
阅读更多

原型

在使用JavaScript的面向对象编程中,原型对象是个核心概念。在JavaScript中对象是作为现有示例对象(即原型)的副本而创建的,该名称就来自于这一概念。此原型对象的任何属性和方法都将显示为从原型的构造函数创建的对象的属性和方法。可以说,这些对象从其原型继承了属性和方法。当您创建如下所示的新Dog对象时:

 

var buddy = new Dog('Buddy');

 

buddy所引用的对象将从它的原型继承属性和方法,尽管仅从这一行可能无法明确判断原型来自哪里,对象buddy的原型来自构造函数(在这里是函数Dog)的属性。

在JavaScript中,每个函数都有名为"prototype"的属性,用于引用原型对象。此原型对象又有名为"constructor"的属性,它反过来引用函数本身。这是一种循环引用,图3更好地说明了这种循环关系。



 图 3 每个函数的原型都有一个 Constructor 属性 

现在,通过"new"运算符用函数(上面示例中为Dog)创建对象时,所创建的对象将继承Dog.prototype属性。在图3中,可以看到Dog.prototype对象有一个回指Dog函数的构造函数属性。这样,每个Dog对象(从Dog.prototype继承而来)都有一个回指Dog函数的构造函数属性。图4中的代码证实了这一点。图5显示了构造函数、原型对象以及它们创建的对象之间的这一关系。

var spot = new Dog(“Spot”);

// Dog.prototype is the prototype of spot
alert(Dog.prototype.isPrototypeOf(spot)); // 说明spot对象是从原型继承来的

// spot inherits the constructor property
// from Dog.prototype
alert(spot.constructor == Dog.prototype.constructor); 
/*
 * 上例说明:
 * 说明构造函数都有一个名为"prototype"的属性,该属性指向原型, 
 * 而原型又有一个指向构造函数的属性"constructor",很显然这是
 * 一个圈(循环引用)。
 */ 
alert(spot.constructor == Dog); 
/*
 * 上例说明:
 * 因为每个对象都继承自原型,所以每个对象都从原型中继承了constructor
 * 属性,而这个属性指向构造函数。
  */

// But constructor property doesn’t belong
// to spot. The line below displays “false”
alert(spot.hasOwnProperty(“constructor”)); 

// The constructor property belongs to Dog.prototype
// The line below displays “true”
alert(Dog.prototype.hasOwnProperty(“constructor”));

/ *
  * 上面两个例子第一个alert弹出的提示是false,第二个是true,
  * 这再次说明了,"constructor"属性不是对象本身的属性,
  * 而是来自于对象的原型。
  */

 



 图 5 实例继承其原型

某些读者可能已经注意到图4中对hasOwnProperty和isPrototypeOf方法的调用。这些方法是从哪里来的呢〉它们不是来自Dog.prototype。实际上,在Dog.prototype和Dog实例中还可以调用其他方法,比如:toString()、toLocaleString和valueOf,但它们都不来自Dog.prototype。您会发现,就像.NET Framework中的System.Object充当所有类的最终基类一样,JavaScript中的Object.prototype是所有原型的最终基础原型。(Object.prototype的原型是null)

在此示例中,请记住Dog.prototype是对象。它是通过调用Object构造函数创建的(尽管它不可见):

Dog.prototype = new Object();

 因此,正如Dog实例继承Dog.prototype一样,Dog.prototype继承Object.prototype。这使得所有Dog实例也继承了Object.prototype的方法和属性。所以每个Dog实例也就继承了我们上面说的toString、toLocaleString、hasOwnProperty方法了。

每个JavaScript对象都继承一个原型链,而所有原型都终止于Object.prototype。注意,迄今为止您看到的这种继承是活动对象之间的继承。它不同于继承的常见概念,后者是指在声明类时类之间的发生的继承,因此,JavaScript继承动态性更强。它使用简单算法实现这一点,如下所示:当您尝试访问对象的属性/方法时,JavaScript将检查该属性/方法是否是在该对象中定义的。如果不是,则检查对象的原型,如果还不是,则检查该对象的原型的原型,如此继续,一直检查到Object.prototype。图6说明了此解析过程。


图 6 在原型链中解析 toString() 方法

JavaScript动态地解析属性访问和方法调用的方式产生了一些特殊效果:

  • 继承原型对象的对象上可以立即呈现对原型所作的更改,即使是在创建这些对象之后。
  • 如果在对象中定义了属性/方法 X,则该对象的原型中将隐藏同名的属性/方法。例如:通过在Dog.prototype中定义toString方法,可以改写Object.prototype的toString方法。
  • 更改只沿一个方向传递,即从原型到它的派生对象,但不能沿相反方向传递。

图7说明了这些效果。图7还显示了如何解决前面遇到的不需要的方法实例的问题。通过将方法放在原型内部,可以使对象共享方法,而不必使每个对象都有单独的函数对象实例。在此示例中,rover和spot共享getBreed方法,直至在spot中以任何方式改写toString方法。此后,spot有了它自己版本getBreed方法,但rover对象和用新GreatDane创建的后续对象仍共享在GreatDane.prototype对象中定义的那个getBreed方法实例。

Figure 7  继承原型

function GreatDane() { }

var rover = new GreatDane();
var spot = new GreatDane();

GreatDane.prototype.getBreed = function() {
    return 'Great Dane';
};

// Works, even though at this point
// rover and spot are already created.
alert(rover.getBreed());

// this hides getBreed() in GreatDane.prototype
spot.getBreed = function() {
    return 'Little Great Dane';
};
alert(spot.getBreed()); 

// but of course, the change to getBreed 
// doesn’t propagate back to GreatDane.prototype
// and other objects inheriting from it,
// it only happens in the spot object
alert(rover.getBreed());

  下一节:静态属性和方法                                                                                                     返回首页: Top

  • 大小: 3.3 KB
  • 大小: 7.1 KB
  • 大小: 19.2 KB
分享到:
评论

相关推荐

    郝振明——驱动原生型移动应用的跨平台实践

    在移动应用开发领域,跨平台技术的实践已经历了多种形态的发展,而“驱动原生型”技术是其中的一个新兴概念。在本篇文档中,郝振明先生提出了“驱动原生型移动应用的跨平台实践”,并且在MDCC 2016中国移动开发者...

    基于深度神经网络的原发性肝癌证型诊断分类预测模型.pdf

    "基于深度神经网络的原发性肝癌证型诊断分类预测模型" 本研究旨在建立基于深度神经网络的原发性肝癌证型诊断分类预测模型,以提高中医证型分类的准确性和科学性。通过收集1176例肝癌病患者的病历资料,包括中医症状...

    java基础入门教程

    另 外 ,由 JavaSoft 推 出 的 完 全 用 Java编 写 的 Internet上 新 型 浏览器 HotJava,比 去 年alpha版 更 为 实 用 ,不 仅 能 编 制 动 态 的 应 用 软件 ,而 且 能 编 制 完整 的 成 套 桌 面 应 用软 件 ,将 来 ...

    主治医师 (全科医学)-传染病(A1-A2型题 2).doc

    肺结核的临床类型包括:I型(原发型肺结核),II型(血行播散型肺结核),III型(继发性肺结核),IV型(结核性胸膜炎),V型(其他肺外结核)。案例1和案例2中的患者均出现咳嗽、乏力、午后潮热、消瘦等症状,并有...

    吉林大学白求恩第二医院刘斌PPT课件.pptx

    混合型心肌病是指同时存在多种心肌病变的疾病,包括扩张型心肌病和原发限制型心肌病。扩张型心肌病是指心室扩大、心功能下降的疾病,病因广泛,主要为感染因素、毒素、酗酒、化疗药物、自身免疫性和系统性疾病等。 ...

    人体免疫学之自身免疫.ppt

    自身免疫病的免疫损伤机制可以分为四种类型:Ⅰ型、Ⅱ型、Ⅲ型和Ⅳ型超敏反应。这些反应涉及不同类型的自身抗体和效应细胞,针对不同的靶抗原发起攻击。以类风湿性关节炎为例,这是一种属于Ⅲ型超敏反应的自身免疫性...

    汽车球笼式等速万向节和总成.doc

    5. 遵循原车型的装配要求,如外轮螺栓、外花键的长度和轮花键与芯轴的配合。 制造流程涉及锻造坯料的初步检查、粗车、精车、铣削、热处理、磨削等多个步骤,每个环节都有严格的尺寸和外观质量要求,确保最终产品在...

    胸部影像诊断学02PPT学习教案.pptx

    根据中华结核病学会1998年的分类标准,结核病主要分为原发型肺结核和血行播散型肺结核两大类。 原发型肺结核是指人体首次感染结核杆菌后的肺部病变,常见于儿童和青少年。其病理特征为原发灶的形成,伴随淋巴管炎和...

    病理习题集-传染病复习思考题.pdf

    - 原发性肺结核常见于儿童,包括原发病灶、淋巴管道扩散和肺门淋巴结肿大,合称肺原发综合征。 - 结核病基本病变的转化规律包括渗出、增生、干酪样坏死和纤维化。 - 结核病的病变特点是炎症渗出和免疫反应性增生...

    胸部影像诊断学021PPT学习教案.pptx

    针对肺结核,我们主要关注两大类分类:原发型肺结核和血行播散型肺结核。原发型肺结核主要见于儿童和青少年群体,其特征为原发综合征的出现。该综合征包含了三个主要组成部分:原发灶(急性渗出性病变)、淋巴管炎...

    海西经济区电子信息产业集群浅析.pdf

    总结来说,海西经济区电子信息产业集群的构建是推动区域经济发展的重要途径,通过结合“原发型”和“嵌入型”集群的优势,有效利用与台湾的地理和历史联系,可以打造出具有竞争优势的电子信息产业基地,为海西经济区...

    ISO12233 分辨率测试卡-增强型原图

    ISO12233分辨率测试卡是一种国际标准化的测试工具,用于评估和测量相机及其他成像设备的分辨率性能。这种测试卡遵循ISO 12233标准,该标准在2000年被发布,旨在提供一种统一的方法来衡量和报告摄影设备的空间分辨率...

    护士资格考试儿科护理学备考—小儿结核病的临床特点.docx

    - 原发型肺结核:是最常见类型,包括原发综合征和肺门淋巴结结核。多见于儿童,病灶通常位于右肺上叶下部。原发病灶可能自然吸收,但淋巴结的干酪样病变可能导致支气管淋巴结结核。 - 血行播散型肺结核:分为急性...

    冠心病介入有效治疗讲义.ppt

    不稳定性心绞痛(UA)是冠心病的一种危险状态,Braunwald将其分为继发型(A)、原发型(B)和心肌梗死后(C)三类,并依据其严重程度和治疗强度进一步细分。不稳定性心绞痛可以迅速发展为急性冠脉综合征(ACS),...

    结核病形成及预防教案归类.pdf

    结核病分为五种类型:原发型肺结核(Ⅰ型)、血行播散型肺结核(Ⅱ型)、浸润型肺结核(Ⅲ型)、慢性纤维空洞型肺结核(Ⅳ型)以及结核性胸膜炎(Ⅴ型)。 【教学反思】 在教学过程中,应当注重案例与实际生活的...

    内科护理学重点总结.doc

    - **临床分型**:原发型、血型播散型、继发型、慢性纤维空洞型。 - **特点**:原发型通常表现为“哑铃”型X线图像;血型播散型表现为均匀分布的粟粒状阴影,病情急重。 - **护理措施**:隔离感染源,保证充足营养...

    内科护理学-肺结核病人护理.ppt

    肺结核的临床分型包括原发型、血行播散型、继发型和结核性胸膜炎等,不同类型具有不同的病理特征和临床表现。原发型肺结核通常发生于初次感染结核菌的儿童和青少年;血行播散型肺结核则是指结核菌通过血液循环播散到...

    医学影像学简答题.doc

    2. 分型:原发型、血行播散型、继发型、结核性胸膜炎等。 3. 原发型:哑铃状,包括原发浸润灶、淋巴管炎、肺门纵隔淋巴结增大。 4. 血行播散型:大小、密度、分布均匀的病灶。 5. 继发型:浸润性、干酪性肺炎、结核...

Global site tag (gtag.js) - Google Analytics