- 浏览: 407621 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (318)
- js (20)
- JQuery (2)
- Java (46)
- Oracle (4)
- mysql (21)
- ExtJs (17)
- Excel (2)
- Linux (8)
- Sql (8)
- Jsp (2)
- hibernate (12)
- jbpm (17)
- eclipse (8)
- 名博收藏 (1)
- Junit (2)
- 应用集成 (3)
- web (10)
- jboss (3)
- Rest (3)
- 其它 (7)
- 磁盘分区管理 (1)
- spring (18)
- SSO (4)
- tomcat (4)
- CSS (7)
- MemCached (6)
- EhCache (4)
- weblogic (1)
- apache (6)
- Exception design (1)
- db (1)
- 分析模式 (1)
- jstl (1)
- jsf (0)
- firefox (2)
- MongoDB (4)
- androidpn (1)
- hadoop (1)
- cvs (1)
- 微信公众号 (2)
- 高并发 (4)
- 技术论坛 (1)
- CDN (1)
- JVM (16)
- 加密 (4)
- maven (2)
- jenkins (1)
- hessian (1)
- 大数据处理 (2)
- NIO (0)
- netty (1)
- redis (1)
- git (1)
- Elastic Job (0)
最新评论
-
zgw06629:
或者<pre>aaaabbbbcccc</p ...
javaDoc注释换行 -
ddnzero:
...
StringBuffer换行 -
maosijun:
。。。。
EXT CExt.form.ComboBox选择一次后只剩一个选项 -
ysa198584:
你这有问题,当我的代码出现User.class的时候,反编绎的 ...
java的class文件批量反编译 -
dongj0325:
看到您的博客,很受启发,但还有关于jbpm4.4 timer使 ...
JBPM定时器(Timer)之Repeat属性不能使用变量
JS原型及原型实现的继承
<!--info-->
原型和闭包是Js语言的难点,此文主要讲原型及原型实现的继承,在(二)中会讲下闭包,希望对大家有所帮助。若有疑问或不正之处,欢迎提出指正和讨论。
一、原型与构造函数
Js所有的函数都有一个prototype属性,这个属性引用了一个对象,即原型对象,也简称原型。这个函数包括构造函数和普通函数,我们讲的更多是构造函数的原型,但是也不能否定普通函数也有原型。譬如普通函数:
以下为引用的内容: function F(){ |
构造函数,也即构造对象。首先了解下通过构造函数实例化对象的过程。
以下为引用的内容: function A(x){ |
实例化obj对象有三步:
1. 创建obj对象:obj=new Object();
2. 将obj的内部__proto__指向构造他的函数A的prototype,同时,obj.constructor===A.prototype.constructor(这个是永远成立的,即使A.prototype不再指向原来的A原型,也就是说:类的实例对象的constructor属性永远指向"构造函数"的prototype.constructor),从而使得obj.constructor.prototype指向A.prototype(obj.constructor.prototype===A.prototype,当A.prototype改变时则不成立,下文有遇到)。obj.constructor.prototype与的内部_proto_是两码事,实例化对象时用的是_proto_,obj是没有prototype属性的,但是有内部的__proto__,通过__proto__来取得原型链上的原型属性和原型方法,FireFox公开了__proto__,可以在FireFox中alert(obj.__proto__);
3. 将obj作为this去调用构造函数A,从而设置成员(即对象属性和对象方法)并初始化。
当这3步完成,这个obj对象就与构造函数A再无联系,这个时候即使构造函数A再加任何成员,都不再影响已经实例化的obj对象了。此时,obj对象具有了x属性,同时具有了构造函数A的原型对象的所有成员,当然,此时该原型对象是没有成员的。
原型对象初始是空的,也就是没有一个成员(即原型属性和原型方法)。可以通过如下方法验证原型对象具有多少成员。
以下为引用的内容: var num=0; |
但是,一旦定义了原型属性或原型方法,则所有通过该构造函数实例化出来的所有对象,都继承了这些原型属性和原型方法,这是通过内部的_proto_链来实现的。
譬如
A.prototype.say=function(){alert("Hi")};
那所有的A的对象都具有了say方法,这个原型对象的say方法是唯一的副本给大家共享的,而不是每一个对象都有关于say方法的一个副本。
二. 原型与继承
首先,看个简单的继承实现。
以下为引用的内容: 1 function A(x){
4 function B(x,y){
5 this.tmpObj=A; 6 this.tmpObj(x); 7 delete this.tmpObj; 8 this.y=y; 9 } |
第5、6、7行:创建临时属性tmpObj引用构造函数A,然后在B内部执行,执行完后删除。当在B内部执行了this.x=x后(这里的this是B的对象),B当然就拥有了x属性,当然B的x属性和A的x属性两者是独立,所以并不能算严格的继承。第5、6、7行有更简单的实现,就是通过call(apply)方法:A.call(this,x);
这两种方法都有将this传递到A的执行里,this指向的是B的对象,这就是为什么不直接A(x)的原因。这种继承方式即是类继承(js没有类,这里只是指构造函数),虽然继承了A构造对象的所有属性方法,但是不能继承A的原型对象的成员。而要实现这个目的,就是在此基础上再添加原型继承。
通过下面的例子,就能很深入地了解原型,以及原型参与实现的完美继承。(本文核心在此)
以下为引用的内容: 1 function A(x){ |
这个例子讲的就是B继承A。第7行类继承:A.call(this.x);上面已讲过。实现原型继承的是第12行:B.prototype = new A();
就是说把B的原型指向了A的1个实例对象,这个实例对象具有x属性,为undefined,还具有a属性,值为"a"。所以B原型也具有了这2个属性(或者说,B和A建立了原型链,B是A的下级)。而因为方才的类继承,B的实例对象也具有了x属性,也就是说obj对象有2个同名的x属性,此时原型属性x要让位于实例对象属性x,所以obj.x是1,而非undefined。第13行又定义了原型方法b2,所以B原型也具有了b2。虽然第9~11行设置了原型方法b1,但是你会发现第12行执行后,B原型不再具有b1方法,也就是obj.b1是undefined。因为第12行使得B原型指向改变,原来具有b1的原型对象被抛弃,自然就没有b1了。
第12行执行完后,B原型(B.prototype)指向了A的实例对象,而A的实例对象的构造器是构造函数A,所以B.prototype.constructor就是构造对象A了(换句话说,A构造了B的原型)。
alert(B.prototype.constructor)出来后就是"function A(x){...}" 。同样地,obj.constructor也是A构造对象,alert(obj.constructor)出来后就是"function A(x){...}" ,也就是说B.prototype.constructor===obj.constructor(true),但是B.prototype===obj.constructor.prototype(false),因为前者是B的原型,具有成员:x,a,b2,后者是A的原型,具有成员:a。如何修正这个问题呢,就在第16行,将B原型的构造器重新指向了B构造函数,那么B.prototype===obj.constructor.prototype(true),都具有成员:x,a,b2。
如果没有第16行,那是不是obj = new B(1,3)会去调用A构造函数实例化呢?答案是否定的,你会发现obj.y=3,所以仍然是调用的B构造函数实例化的。虽然obj.constructor===A(true),但是对于new B()的行为来说,执行了上面所说的通过构造函数创建实例对象的3个步骤,第一步,创建空对象;第二步,obj.__proto__ === B.prototype,B.prototype是具有x,a,b2成员的,obj.constructor指向了B.prototype.constructor,即构造函数A;第三步,调用的构造函数B去设置和初始化成员,具有了属性x,y。虽然不加16行不影响obj的属性,但如上一段说,却影响obj.constructor和obj.constructor.prototype。所以在使用了原型继承后,要进行修正的操作。
关于第12、16行,总言之,第12行使得B原型继承了A的原型对象的所有成员,但是也使得B的实例对象的构造器的原型指向了A原型,所以要通过第16行修正这个缺陷。
实验代码:
function A(){ var a= 12; function B(){ var c= 13; } } alert(A); alert(A.prototype.constructor); alert(A.prototype.constructor==A); var e = new A(); A.c=function C(){ var c=1; alert("A.c():"+c); } alert("A.constructor:"+A.constructor); alert("A.c:"+A.c); alert("A.c():"+A.c()); alert("A.prottype.a:"+A.prototype.a); alert("A:"+A); alert("a.prototype:"+e.__proto__.a); alert("e.__proto__:"+e.__proto__); alert("e.__proto__.constructor:"+e.__proto__.constructor); alert("e.__proto__.constructor.prototype.constructor:"+e.__proto__.constructor.prototype.constructor); alert(e.constructor); A.prototype.a=2; alert("A.prototype.a:"+A.prototype.a); alert("e.__proto__.a:"+e.__proto__.a);
发表评论
-
Javascript继承机制的设计思想
2012-04-25 15:52 697转自: http://blog.csdn.net/ben_g ... -
js闭包几种写法
2012-04-18 14:07 834访问:http://wwww.iteye.com/blog/5 ... -
js arguments对象
2012-04-13 10:12 560在javascript中,不需要明确指出参数名,就能访问它们。 ... -
js call
2012-04-12 14:36 554call 方法 请参阅 应用于 ... -
这段js脚本最后面的一对圆括号是什么意思?-----匿名函数
2012-04-11 14:51 1129例(function(){ if(typeof Drag ... -
js闭包
2012-04-05 10:29 691一、什么是闭包? “官 ... -
getBoundingClientRect() 来获取页面元素的位置
2011-06-29 07:40 704http://www.cnblogs.com/qieqing/ ... -
关于JS中的双感叹号
2011-06-14 07:50 1266!!variant will return boolean t ... -
js中apply与call用法
2011-05-14 18:26 1076JavaScript中有一个call和ap ... -
js中2个等号与3个等号的区别
2011-05-08 10:39 1037首先,== equality 等同,= ... -
js call
2011-05-08 08:28 764http://www.cnblogs.com/sweting/ ... -
在滚动div上的div不随滚动条滚动
2010-12-01 17:21 1145在滚动div上的div不随滚动条滚动原因是浮动层样式 z-in ... -
js中的call()与apply()方法
2009-12-30 10:48 909原文:http://canfly2010.itey ... -
解析JS的prototype继承机制
2009-12-30 10:26 1056许多人一直对JS的prototype继承机制不明了,到底在创建 ... -
js正则表达式使用
2009-08-20 15:10 728一,概述 1,正则表达式,可以说是任何一种编程语言都提供的机 ... -
Javascript Closures(javascript闭包概念)
2009-08-03 18:29 790原文:http://hi.baidu.com/ci ... -
5-18 CSS3伪类选择器:nth-child()
2009-08-03 11:30 977原文:http://hi.baidu.com/%C ... -
KeyDown,KeyPress 和KeyUp
2009-07-30 13:18 2170最近在做一个程序,需要实现窗口下的F5 刷新功能。 研究了一 ... -
浅谈js中的Insertion对象
2009-07-30 10:40 766首先,这个对象是其他类似功能的根。它没有任何属性和方法。在这个 ...
相关推荐
javascript原型继承,prototype的使用,可以像java一样继承
理解Javascript原型继承原理
浅析Javascript原型继承,浅析Javascript原型继承
Javascript原型继承Javascript原型继承Javascript原型继承
浅析javascript原型继承机制,浅析javascript原型继承机制
js的继承模式,以及对apply和call的详细介绍
证明你对JavaScript面向对象已经有一定的了解,如还有什么不理解的可以参考《面向对象JS基础讲解,工厂模式、构造函数模式、原型模式、混合模式、动态原型模式》,接下来讲一般通过那些方法完成JavaScript的继承。...
使用js实现继承的七种方式,详细讲解了js中的原型链继承,构造函数继承,组合继承(经典继承),原型式继承,寄生式继承,寄生组合式继承,以及ES6中的继承,描述原理以及实现和要点概述等。
JavaScript中基于原型的继承的实现与分析.pdf
主要介绍了JavaScript使用原型和原型链实现对象继承的方法,简单讲述了javascript原型与原型链的原理,并结合实例形式详细分析了javascript中对象继承的常见实现技巧,需要的朋友可以参考下
实现传统的类继承模型是很简单,但是实现 JavaScript 中的原型继承则要困难的多。 由于 JavaScript 是唯一一个被广泛使用的基于原型继承的语言,所以理解两种继承模式的差异是需要一定时间的,今天我们就来了解一下...
javascript原型继承机制参考.pdf
javascript原型继承机制借鉴.pdf
javascript原型继承机制归类.pdf
本文实例讲述了JS学习笔记之原型链和利用原型实现继承。分享给大家供大家参考,具体如下: 原型链 原型链是一种关系,实例对象和原型对象之间的关系,关系是通过原型(__proto__)来联系的 实例对象中有__proto__,是...
一:js原型继承四步曲 //js模拟类的创建以及继承 //动物(Animal),有头这个属性,eat方法 //名字这个属性 //猫有名字属性,继承Animal,抓老鼠方法 //第一步:创建父类 function Animal(name){ this.name =...
js函数的原型对象constructor默认指向函数本身,原型对象除了有原型属性外,为了实现继承,还有一个原型链指针__proto__,该指针指向上一层的原型对象,而上一层的原型对象的结构依然类似,这样利用__proto__一直...
面向对象概念(对象封装,各种继承,闭包原理,this作用域等)介绍清晰易懂
javascript原型继承机制[整理].pdf