每个函数都有一个 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种设计模式之原型模式:用原型实例指定创建对象的种类,并通过复制、克隆这些原型创建新的对象。
设计模式的原型模式的例子,希望对大家有用~~~~~~~~
设计模式之原型模式的Java版本实现和UML类设计图
这个是http://blog.csdn.net/dawanganban/article/details/9900539博客中java设计模式的源代码。下载前请先看《设计模式——原型模式》一文。
该代码是android应用设计模式之原型模式小例子
设计模式专题之(五)原型模式---设计模式原型模式示例代码(python--c++)
基于Java实现的23种设计模式Demo,抽象工厂模式、建造模式、工厂方法模式、原型模式、单例模式、外观模式、适配器模式等 Java设计模式共有23种,分别为:抽象工厂模式、建造模式、工厂方法模式、原型模式、单例模式...
java设计模式【之】原型模式、深拷贝与浅拷贝【源码】【场景:克隆羊】 * 原型模式(Prototype) * 实现方式: * 需要被克隆的 class类, 重写Object中的clone()方法,并实现Cloneable接口(否则报错 ...
C#23种设计模式样例代码和UML图等 创建型模式(抽象工厂模式、工厂方法模式、单例模式、建造者模式、原型模式); 行为型模式(策略模式、 迭代器模式、原型模式、职责链模式、 模板方法、 命令模式、 解释器模式、 ...
iOS设计模式之原型模式 博客地址:http://blog.csdn.net/ioswyl88219/article/details/17662945
设计模式C++学习之原型模式(Prototype)
Java 经典设计模式讲解以及项目实战 设计模式简介:主要介绍各种设计模式的概念和运用场景等 设计模式综合运用:主要是笔者在实际工作中运用到的一些设计模式综合运用事例的提炼 Spring设计模式简介:主要是讲述...
这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高...
设计模式主要分为三大类: 1.创建型模式:工厂模式、抽象工厂模式、单例模式、建造者模式、原型模式。 2.结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。 4.行为型模式:...
即原型模式,提供一个已经存在的对象进行新对象创建的接口,一般情况下都是使用Clone接口。 此模式非常简单,简单的说就是复制多个当前对象供使用。Prototype模式允许一个对象再创建另外一个可定制的对象,根本...
总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元...
Java 23种设计模式08原型模式.pdf
设计模式分为三大类: 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 ...