Javascript的原型对象和prototype属性

 

 

 

     Javascript中的继承机制是所谓的原型对象继承,通过属性访问机制的特殊性来实现继承的。之前我一直以为所有对象的原型对象就是prototype所指的那个对象。后来在看javascript设计模式的时候发现作者注中有一句话与我之前的理解不同,他说“每个对象都有一个原型对象,但这并不意味着每个对象都有一个prototype属性”。看完我就有点迷茫了,决定彻底把这个死人的原型继承搞搞清楚。然后翻了些文章和书籍,最后终于在javascript权威指南第五版中找到了个人 认为比较权威的解释。关于原型链和属性访问机制我就不再阐述了,这方面可以看看Rocky的文章 写的蛮清楚的 http://blog.csdn.net/rocky_j2ee/archive/2009/03/21/4012385.aspx

 

那我们先从创建对象说起,用new操作符创建对象的时候javascript会做3件事:

 

首先是创建一个空对象(empty object),

然后对这个空对象的原型对象进行赋值,

最后把这个空对象赋值给构造函数的this属性且运行这个构造函数。

 

 

 

function Person(name) {

    this.name = name;

}

var  p = new Person();  相当于以下步骤:

 

 

1. Var p = {};

 

2. p.[[prototype]] = Person.prototype   //这一步是伪代码,实际上一个对象的原型对象是不能通过代码来访问的,

                                                              //这里只是为了说明创建对象的步骤

3. p.methodName = Person ;                  //这样的话Person的this就会指向p

   p.methodName();

 

 

 

 

如果你对第二步不是很明白,那么先把代码放一放,接下来我会详细解释下第二步原型对象的赋值(或者说构造函数和原型对象的关系):上面我提到过在创建完一个空对象后,会初始化这个空对象的原型对象,javascript会把构造函数的一个叫做prototype的属性所指向的对象赋值给当前空对象的原型对象。所有的function都有一个prototype属性,当一个function被定义之后这个属性会被自动的创建和初始化。一个function 的prototype属性的初始值是一个对象(an object),这个对象只有一个属性叫做constructor,而这个constructor 的值就是当前这个函数(或者叫构造函数)。

 

function Person(name) {

    this.name = name;

}


Person === Person.prototype.constructor;   //true

 

所以你对构造函数的prototype属性进行操作:譬如添加属性或方法,又或者重新赋值,都会反映在用这个构造函数创建出来的对象上。对prototype添加方法或属性,所创建的对象也会继承这些方法和属性,重新赋值的话所创建的对象就会继承新的prototype的方法和属性。

 

 

 

接下来总结下一个容易让人误解的提法和一些比较绕人的题目:

1. 所有的对象都有原型对象,但不是每个对象都有prototype属性。

2. prototype属性是函数(function)特有的属性。

3.函数(function)也是一个对象,那么它也有原型对象,它的原型对象和它的prototype属性没有任何关系。

4.一个函数的原型对象是Function.prototype所指向的那个对象。因为所有的function都是Function的实例,Function是所有funciton的构造函数,按照上面的定义,一个对象的原型对象是这个对象的构造函数的prototype所指的那个对象。

 

function Person(name) {

    this.name = name;


var  p = new Person(“Marry”);

 

p 的原型对象是Person.prototype

 

Person 的原型对象是Function.prototype

 

Person.prototype.constructor === Person  //true

 

 

 

 

最后让我们来看下那些经典的继承的例子:


function Person(name){

    this.name = name;

Person.prototype.walk = function () {

    alert(“walking”);

}


function Author(){

}

 

现在有了Author,想要用Author创建出来的对象继承Person那么就把Author的prototype属性重新赋值为一个Person对象

 

Author.prototype = new Person();

 

然后赋值之后原来的Author.prototype.constructor 就不是原来的Author 所以还要

 

Author.prototype.construtor = Author

 

以上两部就是最最基本的原型继承,其他一些涉及到模拟基于类继承中涉及到的superclass不在这篇文章讨论原意范围内。

 

 

 

 

 

自己在 javascript原型继承上也绕了好久一直是一知半解,希望这篇文章对大家有帮助^_^

 

 

 

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值