javascript面向对象技术基础(四)(2)
作者:sdcyst 来源:javaeye 发布时间:2010-02-07 13:15:00
看个具体的例子吧:
function Person(name,sex) { //构造函数 this.name = name; this.sex = sex; } Person.prototype.age = 12; //为prototype属性对应的prototype对象的属性赋值 Person.prototype.print = function() { //添加方法 alert(this.name+"_"+this.sex+"_"+this.age); }; var p1 = new Person("name1","male"); var p2 = new Person("name2","male"); p1.print(); //name1_male_12 p2.print(); //name2_male_12 Person.prototype.age = 18; //改变prototype对象的属性值,注意是操作构造函数的prototype属性 p1.print(); //name1_male_18 p2.print(); //name2_male_18
到目前为止,我们已经模拟出了简单的类的实现,我们有了构造函数,有了类属性,有了类方法,可以创建"实例".
在下面的文章中,我们就用"类"这个名字来代替构造方法,但是,这仅仅是模拟,并不是真正的面向对象的"类".
在下一步的介绍之前,我们先来看看改变对象的prototype属性和设置prototype属性的注意事项:
给出一种不是很恰当的解释,或许有助于我们理解:当我们new了一个对象之后,这个对象就会获得构造函数的prototype属性(包括函数和变量),可以认为是构造函数(类)继承了它的prototype属性对应的prototype对象的函数和变量,也就是说,prototype对象模拟了一个超类的效果.听着比较拗口,我们直接看个实例吧:
function Person(name,sex) { //Person类的构造函数 this.name = name; this.sex = sex; } Person.prototype.age = 12; //为Person类的prototype属性对应的prototype对象的属性赋值, //相当于为Person类的父类添加属性 Person.prototype.print = function() { //为Person类的父类添加方法 alert(this.name+"_"+this.sex+"_"+this.age); }; var p1 = new Person("name1","male"); //p1的age属性继承子Person类的父类(即prototype对象) var p2 = new Person("name2","male"); p1.print(); //name1_male_12 p2.print(); //name2_male_12 p1.age = 34; //改变p1实例的age属性 p1.print(); //name1_male_34 p2.print(); //name2_male_12 Person.prototype.age = 22; //改变Person类的超类的age属性 p1.print(); //name1_male_34(p1的age属性并没有随着prototype属性的改变而改变) p2.print(); //name2_male_22(p2的age属性发生了改变) p1.print = function() { //改变p1对象的print方法 alert("i am p1"); } p1.print(); //i am p1(p1的方法发生了改变) p2.print(); //name2_male_22(p2的方法并没有改变) Person.prototype.print = function() { //改变Person超类的print方法 alert("new print method!"); } p1.print(); //i am p1(p1的print方法仍旧是自己的方法) p2.print(); //new print method!(p2的print方法随着超类方法的改变而改变)
看过一篇文章介绍说javascript中对象的prototype属性相当于java中的static变量,可以被这个类下的所有对象共用.而上面的例子似乎表明实际情况并不是这样:
在JS中,当我们用new操作符创建了一个类的实例对象后,它的方法和属性确实继承了类的prototype属性,类的prototype属性中定义的方法和属性,确实可以被这些实例对象直接引用.但是,当我们对这些实例对象的属性和方法重新赋值或定义后,那么实例对象的属性或方法就不再指向类的prototype属性中定义的属性和方法,此时,即使再对类的prototype属性中相应的方法或属性做修改,也不会反应在实例对象身上.这就解释了上面的例子:
一开始,用new操作符生成了两个对象p1,p2,他们的age属性和print方法都来自(继承于)Person类的prototype属性.然后,我们修改了p1的age属性,后面对Person类的prototype属性中的age重新赋值(Person.prototype.age = 22),p1的age属性并不会随之改变,但是p2的age属性却随之发生了变化,因为p2的age属性还是引自Person类的prototype属性.同样的情况在后面的
print方法中也体现了出来.
通过上面的介绍,我们知道prototype属性在javascript中模拟了父类(超类)的角色,在js中体现面向对象的思想,prototype属性是非常关键的.


猜你喜欢
- 老婆大人让俺帮她通过Excel生成百人的准考证,她们学校打算来一次高考模拟。由于高考改革,每个学生的考试科目不一样,需要自动生成一下。我一个
- 方法一、os.system() 会保存可执行程序中的打印值和主函数的返回值,且会将执行过程中要打印的内容打印出来import os main
- 前言在企业实际应用中,成熟的业务通常数据量都比较大,而单台MySQL服务器在安全性、高可用性和高并发方面都无法满足实际的需求,我们可以在多台
- 一、安装第三方模块首先要下载名为"pymssql"的模块,然后import该模块安装方法 :1.第一种方法:按win+r
- python来写一个试试吧,这里使用了cPAMIE模块,代码如下:代码from cPAMIE import PAMIEie=PAMIE(&q
- Python 相对路径报错:"No such file or directory"'原因及解决方法如果你取相对路
- http.ListenAndServetype Server struct { // 请求监听地址 Addr s
- 首先撰写golang程序exportgo.go:package mainimport "C"import "f
- JavaScript闭包,是JS开发工程师必须深入了解的知识。3月份自己曾撰写博客《JavaScript闭包》,博客中只是简单阐述了闭包的工
- 之前沉迷于使用index删除,然而发现pandas貌似有bug?import pandas as pdimport numpy as npd
- 为什么你写的sql查询慢?为什么你建的索引常失效?通过本章内容,你将学会MySQL性能下降的原因,索引的简介,索引创建的原则,explain
- MySQL分区表概述我们经常遇到一张表里面保存了上亿甚至过十亿的记录,这些表里面保存了大量的历史记录。 对于这些历史数据的清理是一个非常头疼
- 写在之前SQLite 是一个小型的关系型数据库,它最大的特点在于不需要单独的服务、零配置。我们在之前讲过的两个数据库,不管是 MySQL 还
- 前言数学建模的介绍与作用全国大学生数学建模竞赛:全国大学生数学建模竞赛创办于1992年,每年一届,已成为全国高校规模最大的基础性学科竞赛,也
- 这种问题,初学者应该都会遇到,分享给大家做个参考!from urllib.parse import quoteimport string#解
- max找出tensor 的行或者列最大的值:找出每行的最大值:import torchoutputs=torch.FloatTensor([
- 私有变量表示方法在变量前加上两个下划线的是私有变量。class Teacher(): def __init__(self,nam
- 事务日志(Transaction logs)是数据库结构中非常重要但又经常被忽略的部分。由于它并不像数据库中的schema那样活跃,因此很少
- 我们知道 Golang 切片(slice) 在容量不足的情况下会进行扩容,扩容的原理是怎样的呢?是不是每次扩一倍?下面我们结合源码来告诉你答
- 本文实例讲述了MySQL Union合并查询数据及表别名、字段别名用法。分享给大家供大家参考,具体如下:union关键字SELECT s_i