每个函数都有一个 prototype 属性,它指向一个对象,该对象的用途是包含可以由特定类型的所有实例共享的属性和方法。按照字面意思来理解,那个 prototype 就是通过调用构造函数而创建的那个对象实例的原型对象。使用原型对象可以让所有对象实例共享它所包含的属性和方法,而不必在构造函数中定义对象实例的信息,如下面的例子所示。
function Person(){}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){ return this.name };
var person1 = new Person();
alert( person1.sayName() ); // Nicholas
var person2 = new Person();
alert( person2.sayName() ); // Nicholas
默认情况下,所有的原型对象都会自动获得一个 constructor 属性(当然还有从 Object 继承而来的),它包含一个指向 prototype 属性所在函数的指针,而通过这个构造函数还可继续为原型对象添加其他属性和方法。当调用构造函数创建一个新实例后,该实例会有一个内部指针(在此以 [[Prototype]] 来表示)指向构造函数的原型对象。比如下图就展示了上面的例子中各个对象之间的关系。
虽然无法访问到 [[Prototype]],但可以通过原型对象的 isPrototypeOf(obj) 来确定对象之间是否存在这种关系。还可以通过 Object.getPrototypeOf(obj) 返回原型对象的值。
对象实例可以访问保存在原型对象中的值,但不能通过对象实例重写其中的值,而是会屏蔽掉原型对象中的同名属性,这种修改不会影响其他对象实例,而且可以使用 delete 操作符删除对象实例重新定义的属性,从而恢复被屏蔽的属性。
正如上面所述:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。所以当让原型对象等于另一个类型的实例时,此时的原型对象将包含一个指向另一个原型的指针,那个原型相应地也包含这一个指向另一个构造函数的指针。如此层层递进,就构成了实例与原型的链条,即所谓的原型链。
实现原型链有一种基本模式,其代码大致如下。
function SuperType(){
this.property = true;
}
SuperType.prototype.getSuperValue = function(){ return this.property; };
function SubType(){
this.subproperty = false;
}
SubType.prototype = new SuperType(); // 继承了 SuperType
SubType.prototype.getSubValue = function(){ return this.subproperty; };
var instance = new SubType();
alert(instance.getSuperValue()); // true
这里没有使用 SubType 默认提供的原型,而是给它换了一个新原型,就是 SuperType 的实例。所以新原型不仅具有 SuperType 的实例所拥有的全部属性和方法,而且其内部还有一个指向 SuperType 原型的指针。最终结果就是:instance 指向 SubType 的原型,SubType 的原型由指向 SuperType 的原型。getSuperValue() 方法仍然还在 SuperType.prototype 中,当 property 则位于 SubType.prototype 中,因为它是 SuperType 的一个实例属性。不过这里要注意的是,instance.constructor 现在指向的是 SuperType,因为 SubType 的 constructor 实际上是继承自 SuperType 的原型。
事实上,上面所说的原型链还少一环。因为所有引用类型默认都继承了 Object,而这个继承也是通过原型链实现的,因此默认原型都会包含一个指向 Object.prototype 的内部指针,这也正是所有自定义类型都会继承 toString()、valueOf() 等方法的根本原因。结合上面所述,上面这个例子的完整原型链就可以下图来表示。
注:摘自《JavaScript 高级程序设计》第 6 章 -- 面向对象的程序设计。
- 大小: 9.6 KB
- 大小: 25 KB
分享到:
相关推荐
原型模式是设计模式中的一种,它是Java 23种经典设计模式之一,主要用来提高对象创建的效率。在原型模式中,我们通过复制或克隆一个已经存在的对象来创建新的对象,而不是通过构造函数来创建。这种方法尤其适用于当...
原型模式(Prototype Pattern)是软件设计模式中的一种结构型模式,它的主要目的是通过复制已有对象来创建新对象,从而减少创建新对象的成本。在原型模式中,类的实例化过程被替换为对已有实例的克隆操作,尤其适用...
原型模式(Prototype Pattern)是其中一种行为设计模式,主要用于对象创建。它通过复制已有对象来创建新对象,而不是通过传统的构造函数来创建。在Java中,原型模式可以有效地提高性能,特别是在创建复杂对象时。 #...
原型模式(Prototype Pattern)是一种创建型设计模式,它允许我们通过复制现有的对象来创建新对象,而无需知道具体创建过程的细节。这种模式的核心在于,它提供了一种对象克隆的简便方法,使得对象的创建过程对用户...
原型模式是一种创建型设计模式,它提供了一种创建对象的最佳方式。在原型模式中,一个对象可以被克隆以创建新对象,而无需知道具体的创建细节。这种模式在需要重复创建相似对象时非常有用,避免了每次创建新对象时都...
本篇文章将深入探讨“原型模式(Prototype)”这一经典的设计模式,它是面向对象设计的一个重要概念,尤其在C++编程中有着广泛的应用。 原型模式是一种创建型设计模式,它的核心思想是通过复制已有对象来创建新对象,...
原型模式(Prototype Pattern)是其中一种行为设计模式,它允许我们通过复制现有对象来创建新对象,而不是通过传统方式实例化新对象。这一模式尤其适用于创建复杂或昂贵的对象,因为它提供了对象克隆的能力,从而...
### Java设计模式之原型模式深度解析 #### 模式动机 在面向对象编程的世界里,对象的创建往往伴随着复杂的逻辑处理。特别是在某些场景下,对象的构造过程可能涉及大量资源的消耗,例如数据库连接、文件读写等。在...
基于Java实现的23种设计模式Demo,抽象工厂模式、建造模式、工厂方法模式、原型模式、单例模式、外观模式、适配器模式等 Java设计模式共有23种,分别为:抽象工厂模式、建造模式、工厂方法模式、原型模式、单例模式...
java设计模式【之】原型模式、深拷贝与浅拷贝【源码】【场景:克隆羊】 * 原型模式(Prototype) * 实现方式: * 需要被克隆的 class类, 重写Object中的clone()方法,并实现Cloneable接口(否则报错 ...
ava常用设计模式-原型模式 原型模式(Prototype Pattern)是一种创建型设计模式,允许通过复制现有对象来创建新对象,而不是通过实例化类来创建新对象。在需要创建大量相似对象时非常有用,它可以避免重复创建对象...
【设计模式之原型模式】 设计模式是软件工程中的一种最佳实践,是对在特定上下文中反复出现的软件设计问题的解决方案。原型模式属于对象创建型模式,它的主要思想是通过复制已有对象来创建新对象,降低了类的实例化...
设计模式 的分类 总体来说设计模式分为三大类: 创建型模式(5): 工厂方法模式 、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式(7): 适配器模式、装饰器模式、代理模式、外观模式、桥接模式、...
C#23种设计模式样例代码和UML图等 创建型模式(抽象工厂模式、工厂方法模式、单例模式、建造者模式、原型模式); 行为型模式(策略模式、 迭代器模式、原型模式、职责链模式、 模板方法、 命令模式、 解释器模式、 ...
JDK中许多类和方法都使用了设计模式,这些模式的应用帮助实现了代码的高内聚、低耦合,提高了代码的可维护性和扩展性。下面介绍几种常见的设计模式及其在JDK中的应用实例: a) 抽象工厂模式(AbstractFactory) ...
本资料集包含了多种重要的前端设计模式,如工厂模式、原型模式和构造器模式,下面将详细阐述这些模式的核心概念和应用。 1. 工厂模式: 工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式,通过抽象出...