转载地址:http://www.iteye.com/topic/1128242
什么是原型对象?
“我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。”
--摘自人民邮电出版社出版的Nicholas C.Zakas著的《JavaScript高级程序设计》(第2版)
上面提到的对象,就是原型对象,它的用途是“包含可以由特定类型的所有实例共享的属性和方法”。那么怎么才能访问到它呢?按照上面的说法,每个函数都有一个prototype 指针,这个指针指向了它的原型对象,所以我们可以通过函数的prototype属性来访问函数的原型对象。
下面用程序来说明。
- function SuperType(){}
- document.write(SuperType.prototype);//[object Object]
function SuperType(){} document.write(SuperType.prototype);//[object Object]
可见函数SuperType的确存在一个prototype属性,其的确是指向了一个对象。但这个对象真是原型对象吗?怎么证明?上面不是说原型对象的用途是“包含可以由特定类型的所有实例共享的属性和方法”,既然如此,那我们就来看这个对象是不是真的有这个功能。
- function SuperType(){}
- SuperType.prototype.name = 'Sam';//在SuperType.prototype指向的对象上增加了name属性
- //在SuperType.prototype指向的对象上增加了sayName方法
- SuperType.prototype.sayName = function() {
- document.write(this.name);
- };
- SuperType.prototype.setName = function(name) {
- SuperType.prototype.name = name;
- };
- var instance1 = new SuperType();
- var instance2 = new SuperType();
- instance1.sayName();//Sam
- instance2.sayName();//Sam
- instance1.setName('Luce');
- instance1.sayName();//Luce
- instance2.sayName();//Luce
function SuperType(){} SuperType.prototype.name = 'Sam';//在SuperType.prototype指向的对象上增加了name属性 //在SuperType.prototype指向的对象上增加了sayName方法 SuperType.prototype.sayName = function() { document.write(this.name); }; SuperType.prototype.setName = function(name) { SuperType.prototype.name = name; }; var instance1 = new SuperType(); var instance2 = new SuperType(); instance1.sayName();//Sam instance2.sayName();//Sam instance1.setName('Luce'); instance1.sayName();//Luce instance2.sayName();//Luce
当实例instance1调用setName()函数更改了SuperType.prototype.name的值后,instance2.sayName()也会输出Luce,说明SuperType.prototype指向的对象的确是“包含了可以由特定类型(这里是SuperType)的所有实例所共享的属性和方法”,所以由此可以得出结论:
SuperType.prototype指向的就是SuperType的原型对象,也即是函数的prototype属性指向了函数的原型对象。
下面用程序来说明构造函数、实例和原型对象三者之间的关系。
首先是构造函数与实例之间的关系,实例就是通过调用构造函数创立的:
- function SuperType(name){
- this.name = name;
- this.sayName = function(){
- document.write(this.name);
- }
- }
- var instance1 = new SuperType("Sam");
- instance1.sayName();//Sam
- var instance2 = new SuperType("Luce");
- instance2.sayName();//Luce
function SuperType(name){ this.name = name; this.sayName = function(){ document.write(this.name); } } var instance1 = new SuperType("Sam"); instance1.sayName();//Sam var instance2 = new SuperType("Luce"); instance2.sayName();//Luce
我们在构造函数里面定义了一个name属性和一个sayName()函数,当调用new SuperType()创建实例时,就会调用构造函数SuperType创建实例对象,同时为实例对象增加一个name 属性和一个sayName()方法(也即是把this换成了实例对象(如this.name换成了instance1.name),所以每个实例的name和sayName()方法都是独立的,注意和在原型对象上定义的 区别,在原型对象上定义是共享的)。
构造函数与原型对象的关系。前面已经说过,构造函数中有一个prototype属性,该属性是一个指针,指向了它的原型对象,那原型对象呢?是不是在它里面也存在一个指针,指向构造函数呢?答案是的确如此。原型对象中有一个constructor属性,该属性指向了构造函数:
- function SuperType(){}
- document.write(SuperType.prototype.constructor);//function SuperType(){}
- document.write(SuperType.prototype.constructor == SuperType);//true
function SuperType(){} document.write(SuperType.prototype.constructor);//function SuperType(){} document.write(SuperType.prototype.constructor == SuperType);//true
打印SuperType.prototype.constructor,输出的是构造函数的定义,而我们知道函数名只是一个引用,其指向函数所在的地址,所以通过SuperType.prototype.constructor和SuperType的比较,返回了true,所以SuperType.prototype.constructor和SuperType一样都指向了SuperType()函数,在这里即是指向了构造函数。
最后是实例与原型对象的关系。前面的例子可以看到(最开始),实例可以访问到在原型对象上定义的属性和方法,那么我们就可以猜测,实例中肯定有一个指针指向了原型对象,的确如此,实例中有一个属性__proto__(IE中没有这个属性,所以不要在IE下测试),该属性指向了原型对象:
- function SuperType(){}
- var instance = new SuperType();
- document.write(instance.__proto__ == SuperType.prototype);//true
function SuperType(){} var instance = new SuperType(); document.write(instance.__proto__ == SuperType.prototype);//true
SuperType.prototype指向了SuperType的原型对象,而instance.__proto__和SuperType.prototype比较返回了true,这就说明instance.__proto__也指向了SuperType的原型 对象。
以上即是JavaScript原型对象的相关信息。
相关推荐
"javascript事件列表解说(转载).doc"专门讲述了JavaScript中的事件处理,这对于创建响应用户交互的动态页面至关重要。事件是JavaScript与用户进行交互的关键,理解并熟练运用事件可以极大地提升用户体验。 ...
在JavaScript中,对对象进行类型判断是编程过程中常见的需求,特别是在处理动态数据或者需要执行不同操作根据对象类型时。本文将深入探讨如何在JavaScript中判断一个对象是否属于特定的类或构造函数。 首先,...
【JavaScript】JavaScript面试通常涉及DOM操作、BOM处理、异步编程(如回调函数、Promise、async/await)、闭包、原型链、事件循环机制等。面试官可能会要求编写实际的代码示例,以评估你的实战能力。 【Struts】...
3. **对象与原型**:JavaScript的面向对象编程基于原型,通过__proto__属性或Object.create方法实现对象间的继承。ES6引入的class语法糖使得面向对象编程更接近传统语言,但底层仍基于原型。 4. **异步编程**:...
然后,在Vue的原型上挂载Axios实例,以便在任何组件中通过`this.$axios`方便地使用Axios。 ```javascript // main.js import axios from 'axios'; import qs from 'qs'; Vue.prototype.$axios = axios; // demo....
它以简洁易读的语法和强大的开发效率而闻名,广泛用于Web开发、系统管理自动化、以及各种应用程序的原型设计和开发。 2. 作者信息:文档提到的作者是David Flanagan和Yukihiro Matsumoto。David Flanagan是一位知名...