《悟透javascript》学习笔记:九、原型毕露

引言

 

      prototype源自法语,软件界的标准翻译为“原型”,代表事物的初始形态,也含有模型和样板的意义。

 

prototype属性

 

JavaScript的所有function类型的对象都有一个prototype属性。这个prototype属性本身又是一个 object 类型的对象,因此我们也可以给这个 prototype 对象添加任意的属性和方法。既然 prototype是对象的“原型”,那么由该函数构造出来的对象应该都会具有这个“原型”的特性。事实上,在构造函数的prototype上定义的所有属性和方法,都是可以通过其构造的对象直接访问和调用的。也可以这么说,prototype提供了一群同类对象共享属性和方法的机制。运行如下代码,然后观察。

 

<script language="javascript">

function person(name){        //构造函数person

   this.name = name;

   //this创建出的对象,每一个副本都会包含其属性和函数

   this.say = function(){alert("hello, i'm " + this.name);}

}

//prototype创建的函数对象,所有的副本共享同一个函数

person.prototype.show = function(){alert("hi~~, i'm " + this.name);}

 

var p1 = new person("p1");

var p2 = new person("p2");

alert(p1.say == p2.say); //false,没共享函数

alert(p1.show == p2.show);  //true,共享函数

</script>

 

原型链

 

<script language="javascript">

function person(name){

   this.name = name;

}

person.prototype.say = function(){alert("hello, i'm " + this.name);}

 

function employee(name, salary){

   //调用person作为employee的构造函数——重点

   person.call(this, name);      //目的是继承person的属性

   this.salary = salary;

}

//子类构造函数首先需要用上层构造函数来建立 prototype对象,实现继承的概念——重点

employee.prototype = new person(); //目的是继承person的方法,只需要其 prototype 的方法,此对象的成员没有任何意义!

employee.prototype.showMoney = function(){alert(this.name + "'s salary is " + this.salary);}

 

var bill = new person("BillGates");

var jeck = new employee("jeck baoer", 5000);

bill.say();

jeck.say();

jeck.showMoney();

alert(bill.say == jeck.say);

</script>

 

      employee.prototype = new person();这段代码,构造了一个基类的对象,并将其设为子类构造函数的prototype,这是很有意思的。这样做的目的就是为了jeck.say();这句,通过子类对象也可以直接调用基类 prototype 的方法。为什么可以这样呢?

 

原来,在 JavaScript 中,prototype 不但能让对象共享自己财富,而且 prototype 还有寻根问祖的天性,从而使得先辈们的遗产可以代代相传。当从一个对象那里读取属性或调用方法时,如果该对象自身不存在这样的属性或方法,就会去自己关联的prototype对象那里寻找;如果prototype没有,又会去 prototype自己关联的前辈prototype那里寻找,直到找到或追溯过程结束为止。

 

JavaScript 内部,对象的属性和方法追溯机制是通过所谓的 prototype 链来实现的。当用 new 操作符构造对象时,也会同时将构造函数的prototype对象指派给新创建的对象,成为该对象内置的原型对象。对象内置的原型对象应该是对外不可见的,尽管有些浏览器(Firefox)可以让我们访问这个内置原型对象,但并不建议这样做。内置的原型对象本身也是对象,也有自己关联的原型对象,这样就形成了所谓的原型链。(这段话我觉得很难理解,那位高手说明下)

 

在原型链的最末端,就是 Object 构造函数 prototype 属性指向的那一个原型对象。这个原型对象是所有对象的最老祖先,这个老祖宗实现了诸如toString等所有对象天生就该具有的方法。其他内置构造函数,如Function, Boolean, String, Date RegExp 等的prototype都是从这个老祖宗传承下来的,但他们各自又定义了自身的属性和方法,从而他们的子孙就表现出各自宗族的那些特征。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值