- 浏览: 476451 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (160)
- jstl (3)
- JavaScript (24)
- JSF (6)
- Seam (6)
- EJB3.0 (0)
- HTML (8)
- Core Java (21)
- IDE (2)
- jquery (13)
- weblogic (2)
- oracle jndi (1)
- cxf (2)
- hbase (3)
- quartz (2)
- mybatis (1)
- storm (2)
- spring (6)
- nginx (2)
- maven (6)
- logback (2)
- svn (2)
- tomcat (1)
- activemq (1)
- kafka (2)
- redis (1)
- eclipse (4)
- 其他 (2)
- zookeeper (1)
- mongodb (1)
- idea (3)
- linux (1)
- docker (2)
- springboot (1)
最新评论
-
sxlkk:
lin_li 写道请问你这里怎么操作的啊?tar xvf su ...
subversion-1.9.3 Linux服务器安装教程 -
lin_li:
请问你这里怎么操作的啊?tar xvf subversion- ...
subversion-1.9.3 Linux服务器安装教程 -
wzwahl36:
json转javabean工具 [url]http://www ...
JAVA解析JSON,json对象转为javabean -
wzwahl36:
json转javabean工具 [url]http://www ...
JAVA解析JSON,json对象转为javabean -
tianxinyang:
楼主谢谢了,
CXF开发webservice需要的最少jar包,CXF发布和调用客户端代码
类、构造函数、原型
先来说明一点:在上面的内容中提到,每一个函数都包含了一个prototype属性,这个属性指向了一个prototype对象(Every
function has a prototype property that refers to a predefined prototype object --section8.6.2).注意不要
搞混了.
构造函数:
new操作符用来生成一个新的对象.new后面必须要跟上一个函数,也就是我们常说的构造函数.构造函数的工作原理又是怎样的呢?
先看一个例子:
Js代码
function Person(name,sex) {
this.name = name;
this.sex = sex;
}
var per = new Person("sdcyst","male");
alert("name:"+per.name+"_sex:"+per.sex); //name:sdcyst_sex:male
function Person(name,sex) { this.name = name; this.sex = sex; } var per = new Person("sdcyst","male"); alert("name:"+per.name+"_sex:"+per.sex); //name:sdcyst_sex:male
下面说明一下这个工作的步骤:
开始创建了一个函数(不是方法,只是一个普通的函数),注意用到了this关键字.以前我们提到过this关键字表示调用该方法的对象,也就
是说通过对象调用"方法"的时候,this关键字会指向该对象(不使用对象直接调用该函数则this指向整个的script域,或者函数所在的域,在此
我们不做详细的讨论).当我们使用new操作符时,javascript会先创建一个空的对象,然后这个对象被new后面的方法(函数)的this关键字引用!然后在方法中
通过操作this,就给这个新创建的对象相应的赋予了属性.最后返回这个经过处理的对象.这样上面的例子就很清楚:先创建一个空对象,然后
调用Person方法对其进行赋值,最后返回该对象,我们就得到了一个per对象.
prototype(原型)--在这里会反复提到"原型对象"和"原型属性",注意区分这两个概念.
在javascript中,每个对象都有一个prototype属性,这个属性指向了一个prototype对象.
上面我们提到了用new来创建一个对象的过程,事实上在这个过程中,当创建了空对象后,new会接着操作刚生成的这个对象的prototype属性.
每个方法都有一个prototype属性(因为方法本身也是对象),new操作符生成的新对象的prototype属性值和构造方法的prototype属性值是一致的.构造方
法的prototype属性指向了一个prototype对象,这个prototype对象初始只有一个属性constructor,而这个constructor属性又指向了prototype属性所在的方法
这样,当用构造函数创建一个新的对象时,它会获取构造函数的prototype属性所指向的prototype对象的所有属性.对构造函数对应的prototype对象
所做的任何操作都会反应到它所生成的对象身上,所有的这些对象共享构造函数对应的prototype对象的属性(包括方法).
看个具体的例子吧:
Js代码
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
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对象模拟了一个超类的效果.听着比较拗口,我们直接看个实例吧:
Js代码
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方法随着超类方法的改变而改变)
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属性
是非常关键的.
先来说明一点:在上面的内容中提到,每一个函数都包含了一个prototype属性,这个属性指向了一个prototype对象(Every
function has a prototype property that refers to a predefined prototype object --section8.6.2).注意不要
搞混了.
构造函数:
new操作符用来生成一个新的对象.new后面必须要跟上一个函数,也就是我们常说的构造函数.构造函数的工作原理又是怎样的呢?
先看一个例子:
Js代码
function Person(name,sex) {
this.name = name;
this.sex = sex;
}
var per = new Person("sdcyst","male");
alert("name:"+per.name+"_sex:"+per.sex); //name:sdcyst_sex:male
function Person(name,sex) { this.name = name; this.sex = sex; } var per = new Person("sdcyst","male"); alert("name:"+per.name+"_sex:"+per.sex); //name:sdcyst_sex:male
下面说明一下这个工作的步骤:
开始创建了一个函数(不是方法,只是一个普通的函数),注意用到了this关键字.以前我们提到过this关键字表示调用该方法的对象,也就
是说通过对象调用"方法"的时候,this关键字会指向该对象(不使用对象直接调用该函数则this指向整个的script域,或者函数所在的域,在此
我们不做详细的讨论).当我们使用new操作符时,javascript会先创建一个空的对象,然后这个对象被new后面的方法(函数)的this关键字引用!然后在方法中
通过操作this,就给这个新创建的对象相应的赋予了属性.最后返回这个经过处理的对象.这样上面的例子就很清楚:先创建一个空对象,然后
调用Person方法对其进行赋值,最后返回该对象,我们就得到了一个per对象.
prototype(原型)--在这里会反复提到"原型对象"和"原型属性",注意区分这两个概念.
在javascript中,每个对象都有一个prototype属性,这个属性指向了一个prototype对象.
上面我们提到了用new来创建一个对象的过程,事实上在这个过程中,当创建了空对象后,new会接着操作刚生成的这个对象的prototype属性.
每个方法都有一个prototype属性(因为方法本身也是对象),new操作符生成的新对象的prototype属性值和构造方法的prototype属性值是一致的.构造方
法的prototype属性指向了一个prototype对象,这个prototype对象初始只有一个属性constructor,而这个constructor属性又指向了prototype属性所在的方法
这样,当用构造函数创建一个新的对象时,它会获取构造函数的prototype属性所指向的prototype对象的所有属性.对构造函数对应的prototype对象
所做的任何操作都会反应到它所生成的对象身上,所有的这些对象共享构造函数对应的prototype对象的属性(包括方法).
看个具体的例子吧:
Js代码
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
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对象模拟了一个超类的效果.听着比较拗口,我们直接看个实例吧:
Js代码
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方法随着超类方法的改变而改变)
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属性
是非常关键的.
发表评论
-
js格式化金额
2016-12-02 14:56 492/* * formatMoney(num,ty ... -
分享自己编写的一个jquery日历控件,可以选择日期区间
2014-08-01 17:08 1729先来个截图 初版未经全面测试,难免有bug, ... -
jquery的slideUp、slideDown在IE中的闪动bug-完美解决
2014-02-26 13:47 7567最近用到了jquery的一个收缩特效,但是发 ... -
$.extend(),与$.fn.extend()
2014-01-23 12:17 815jQuery插件的开发包括两种: 一种是类级别的插件开发, ... -
JS event 属性详解
2013-12-06 14:45 876Event属性和方法: 1. type ... -
JAVA解析JSON,json对象转为javabean
2012-11-15 14:32 15424一json-lib.jar开发包使用依赖包 json-lib. ... -
关于iframe的滚动条
2012-11-14 09:53 2218最近研究了一下iframe的滚动条,iframe本身 ... -
iframe载入完成时的事件监听
2012-11-14 09:41 1593经常会遇到这样一种情况。 在iframe里嵌入另外一个页面 ... -
JAVA和JSON数据对象转换
2011-01-11 16:59 1616JSON-lib这个Java类包用于把bean,map和XML ... -
JS读取本地文本文件(不用fso)
2010-12-08 17:22 2161<SCRIPT> //<!-- fu ... -
js关闭窗口不出现提示框
2010-07-01 09:42 1551function closeWindow() { ... -
js 判断对象为空或者不是对象的方法
2010-05-13 09:59 9128在写js脚本的时候经常遇到对象为空或者不是对象的情况,出现这种 ... -
a href=#与 a href=javascript:void(0)
2010-05-12 13:58 1550<a href="javascript:voi ... -
location.href
2009-12-28 15:24 1805"window.location.href" ... -
js去除字符串空格函数
2009-05-07 19:14 4051运用正则表达式去除字符串的空格 <script ty ... -
js判断是否是正整数,js判断是否是数字
2009-04-24 12:53 42637//判断字符串是否为数字 function checkR ... -
document.location
2009-04-08 15:39 2147document.location="url&quo ... -
图片自动滚动效果
2009-02-26 12:05 4600说明:兼容火狐和IE,上下滚动代码需去掉HTML页面顶部一行! ... -
双击滚动条自动滚动,单击停下
2009-02-23 12:34 1545就是这么简单: <body onDblClick=&q ... -
javascript面向对象技术基础(五)
2009-02-23 12:29 1115类变量/类方法/实例变量/实例方法 先补充一下以前写过的方法: ...
相关推荐
javascript面向对象技术基础,javascript面向对象技术基础
javascript面向对象技术基础 整理排版了一下 外带了个闭包的文章,下了可以直接打印了
一个很好的学习javascript的资料,详细叙述了javascript面向对象的原理,并含有大量的程序例子说明。非常实用。
看了很多介绍javascript面向对象技术的文章,很晕.为什么?不是因为写得不好,而是因为太深奥.
看了很多介绍javascript面向对象技术的文章,很晕.为什么?不是因为写得不好,而是因为太深奥.javascript中的对象还没解释清楚怎么回事,一上来就直奔主题,类/继承/原型/私有变量....
本教程针对那些对javascript语言有一定的了解,从事过web开发,并且在实际中或多或少地使用过javascript的开发和技术人员 javascript语言基础的语法在此就直接略过,不做介绍 通过本教程的学习,学习者应该了解...
5.1 JavaScript编程基础 5.1.1 JavaScript简介 5.1.2 Javascript的使用方法 5.1.3 语法规则 5.1.4 运算符和表达式 5.1.5 函数 5.1.6流程控制 5.1.7 事件处理 5.2 JavaScript对象编程 5.2.1 Object 类型 5.2.2 Array...
JavaScript对象,数组,字符串,使用正则表达式操纵字符串,客户端,控制文档结构的模型,JavaScript事件驱动模型,CSS,Cookie,XML和JSON,Ajax,深入JavaScript面向对象编程,深入JavaScript函数式编程,深入...
本书是一部独具特色的面向对象技术著作。书中结合代码示例生动透彻地讲述了面向对象思想的精髓,让读者真正学会以对象方式进行思考。此外,本书还讨论了各种与面向对象概念密切相关的应用主题,包括XML、UML建模语言...
数组,字符串,使用正则表达式操纵字符串,客户端,控制文档结构的模型,JavaScript事件驱动模型,CSS,Cookie,XML和JSON,Ajax,深入JavaScript面向对象编程,深入JavaScript函数式编程,深入JavaScript动态化编程...
-(4) JavaScript面向对象的支持--(5) JavaScript面向对象的支持--(6) JavaScript精简学习1:基础知识 JavaScript精简学习2:浏览器输出 JavaScript精简学习3:图像 JavaScript精简学习4:表单 ...
从颇具深度的JavaScript语言基础到作用域(链),从引用类型到面向对象编程,从极其灵活的匿名函数到闭包的内部机制,从浏览器对象模型(BOM)、文档对象模型(DOM)到基于事件的Web脚本设计,从XML(E4X)到Ajax及JSON,从...
《JavaScript核心概念及实践》不仅帮助读者迅速掌握JavaScript基础知识和核心技术,而且通过实例讲解如何将这些知识和技术理解应用到实际工作中,提升编程能力,以简洁、优美的代码开发出功能强大且更易于维护和扩展...
JavaScript高级篇:揭示JavaScript的运行机理和高级应用,如面向对象编程、函数式编程和元编程。Ajax篇:Ajax是上帝赐予JavaScript的礼物。凭借着Ajax,JavaScript拥有了异步调度服务端业务逻辑的能力。本篇除介绍...
JavaScript高级篇:揭示JavaScript的运行机理和高级应用,如面向对象编程、函数式编程和元编程。Ajax篇:Ajax是上帝赐予JavaScript的礼物。凭借着Ajax,JavaScript拥有了异步调度服务端业务逻辑的能力。本篇除介绍...
9.6 JavaScript中的面向对象技术 9.7 子类 9.8 ECMAScript 5 中的类 9.9 模块 第10章 正则表达式的模式匹配 10.1 正则表达式的定义 10.2 用于模式匹配的String方法 10.3 RegExp对象 第11章 JavaScript的子集和扩展 ...