[转帖]javascript原型分析研究_Tomcat, WebLogic及J2EE讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  Tomcat, WebLogic及J2EE讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 2986 | 回复: 0   主题: [转帖]javascript原型分析研究        下一篇 
    本主题由 koei 于 2014-5-2 16:06:46 移动
wangxilu
注册用户
等级:少校
经验:850
发帖:73
精华:3
注册:2013-4-10
状态:离线
发送短消息息给wangxilu 加好友    发送短消息息给wangxilu 发消息
发表于: IP:您无权察看 2013-4-22 14:28:33 | [全部帖] [楼主帖] 楼主

原型是个很微妙的东西,很多人不是很理解,理解了原型对于研究其他js类的框架(比方Extjs)很有帮助.

下面我们开始讨论下原型,对于理解js中的原型概念十分重要。简单来说,一个原型类似其他语言中的一个类,它定义的属性且可以被此类产生的所有对象

所共享。然而它又不像一个类,原型可以在运行时获得和改变。可以增加属性到原型上或者删除原型上已经存在的属性。所有的变化将立即影响由原型派生的对象。

它是如何工作的呢? 

js是一种动态的语言,它不是在编译期间去搜索属性值,而是在执行请求期间去搜索属性值。例如,考虑一个基本的继承案例,A的原型继承自B的原型,a对象

是由A的原型派生出的对象.如果对象a上的一个属性被请求,则js表现出如下搜索过程:

js首先检查a对象上是否存在此属性,如果没有搜索到,则进行第2部分搜索过程。

js访问A的原型检查是否有此属性,如果仍然没搜到,则进行第3部分搜索过程。

js最后访问B的原型检查是否有此属性.如果没有搜到将访问每个父类对象上的原型直到达到根原型上。这样的一个搜索过程称原型链。

如下图所示:

下面我来出一个js原型的题目:

复制内容到剪贴板

代码:

function F() { }
F.prototype.someProperty = prototype property;
var a = new F();
alert(a.someProperty);
a.someProperty = object property;
alert(a.someProperty);
a.someProperty = undefined;
alert(a.someProperty);
delete a.someProperty
alert(a.someProperty);
1=》prototype property
2=》object property
3=》undefined
4=>prototype property


解析:第1个先搜索a对象上是否存在someProperty属性,发现没有,则搜索它的原型发现有someProperty属性 值返回。

第2个依然先搜索a对象上是否存在someProperty属性,发现有,返回。

分析第3个前说下 a.someProperty = undefined; 虽然赋值undefined但a对象上依然有someProperty属性。

所以 第3个依然先搜索a对象上是否存在someProperty属性,发现有,返回

所以 第4个依然先搜索a对象上是否存在someProperty属性,由于delete a.someProperty此操作已经删除了a对象上的someProperty属性, 所以搜索它的原型发现有,返回。

到此大家应该对原型有一个比较清楚的认识。

js中创建对象方式一般如下:

function f(){

}

js每次声明新函数的过程中,都会为其创建一个 prototype 的属性。在未加其他附带条件情况下,所有函数的 prototype 属性有一个 

constructor 属性,constructor 包含一个指向 prototype 属性所属函数的指针(就是说 constructor 

回指构造函数本身),这表明alert(f.prototype.constructor ==f)结果为true。

分析图如下:

下面讲讲2个写法的区别:

方式1:function f(){

this.name=xxx
}


方式2:function f(){

}
f.prototype.name=xxx;


对于以上2种方式定义,如果var f1 = new 

f() 虽然alert(f1.name)效果一样,但是对于方式1,有f产生的对象每个上面都有name属性,即每个对象都有一份内存使用,如果函数

f内定义的属性更多那么占用的内存可想而知非常大;对于方式2,有f产生的对象每个上面都没有name属性,搜索属性时会按照上文搜索过程最终找

到xxx;所以方式2更加优化。

对于上文如果大家都能理解,我们趁热打铁,说下js的继承。

下面是一种实现js继承的方式

function father(){
}
function sun(){
}
sun.prototype=new father();//这样子类产生的对象都会有父类中的属性,按照之前的原型查找机制很容易理解
sun.prototype.constructor=sun();//由于上一句造成子类的构造函数变成父类的所以子类的构造函数还需还原回来


这样就完成了继承。当然通过前文的分析,此写法还有点缺陷,在内存上不是很优化。

其实可以使用一个空函数作为中介实现更优化的继承。此写法可以参数Extjs2,3版本中继承中的写法。如果本文到此为止您都能懂,想必你完全能看懂ext中继承的写法。

首次在51cto发帖

该贴由koei转至本版2014-5-2 16:06:45




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论