JScript中的prototype(原型)属性研究
今天看到同事使用js中的Prototype,感觉很是新鲜。由此想深入学习一下prototype(英['prəʊtətaɪp]
美['protə'taɪp]
n. 原型;标准,模范),在学习prototype(原型)之前直接给出模仿同事代码写出的测试案例。
案例:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<input type="text" id="txt" />
<input type="button" id="btnPrototypeTest" value="prototypeTest" onclick="test(document.getElementById('txt').value)" />
</div>
</form>
</body>
</html>
<script type="text/javascript">
function JSPrototype() { }
JSPrototype.prototype = {
ShowName: function (name) {
alert(name);
},
ShowAge: function () {
return "的年龄为24";
}
}
var jsPrototype = new JSPrototype();
function test(name) {
jsPrototype.ShowName(name + jsPrototype.ShowAge());
}
</script>
以下内容来自:http://www.cnblogs.com/birdshome/archive/2005/02/17/105403.html
我们知道JScript中对象的prototype属性,是用来返回对象类型原型的引用的。我们使用prototype属性提供对象的类的一组基本功能。并且对象的新实例会"继承"赋予该对象原型的操作。但是这个prototype到底是怎么实现和被管理的呢?
对于对象的prototype属性的说明,JScript手册上如是说:所有 JScript 内部对象都有只读的 prototype 属性。可以向其原型中动态添加功能(属性和方法),但该对象不能被赋予不同的原型。然而,用户定义的对象可以被赋给新的原型。
下面我们看三个经典的prototype属性的使用示例。
1、为脚本环境内建对象添加方法:
; i < this.length; i++)
{
if (max < this[i])
max = this[i];
}
return max;
};2、为用户自定义类添加方法:
function TestObject(name)
{
this.m_Name = name;
}
TestObject.prototype.ShowName = function()
{
alert(this.m_Name);
};3、更新自定义类的prototype:
function TestObjectA()
{
this.MethodA = function()
{
alert('TestObjectA.MethodA()');
}
}
function TestObjectB()
{
this.MethodB = function()
{
alert('TestObjectB.MethodB()');
}
}
TestObjectB.prototype = new TestObjectA();第三个很眼熟吧?对啊,它就是我们前面介绍的原型继承法呀~~ 不过今天我们不是研究"继承",之所以可以这样来实现一种继承,只是利用了prototype属性的一个副作用而已。
prototype还有一个默认的属性:constructor,是用来表示创建对象的函数的(即我们OOP里说的构造函数)。constructor属性是所有具有prototype属性的对象的成员。它们包括除Global和Math对象以外的所有JScript内部对象。constructor属性保存了对构造特定对象实例的函数的引用。
弄清楚了JScript中prototype属性怎么使用后,下面我们再来深入的研究它。
JScript中的prototype(原型)属性研究(2)
What's prototype pattern?
Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
原型模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。
继续了解到底什么是prototype pattern,可以参看'设计模式之Prototype(原型)'这篇文章,即使不懂Java也没有关系,把它的代码都当C#看就行了
。
搞清楚什么是原型了吧?反正记着一点,prototype pattern是的实现是依赖于clone这个操作的,当然要shallow copy还是deep copy的clone看自己的需要了。
下面我们继续说JScript里的prototype,为什么我们说它和prototype pattern里的prototype不一样呢?! 这个不是我说就说出来的,也不是我吹出来的,看看这个示例,你就能大概糊涂:

;
RP.MethodA = function()
{
alert("RP.MethodA ");
};
this.PropertyA = 100;
this.MethodA = function()
{
alert("this.MethodA");
};
}
RP.prototype.PropertyA = 10;
RP.prototype.MethodA = function()

{
alert("RP.prototype.MethodA");
};
</script>不要着急,还没有开始做示例,只是给出了我们用来演示的一个类。RP是什么?rpwt吗?当然不是了,RP是ResearchPrototype了
。好了不废话了,看示例及结果分析。

<script language="javascript">
rp = new RP();
alert(RP.PropertyA);
RP.MethodA();
alert(rp.PropertyA);
rp.MethodA();
</script>运行结果闪亮登场:
RP.MethodA
100
this.MethodA
这个%$@#^$%&^...,不要着急,继续看哦!

<script language="javascript">
rp = new RP();
delete RP.PropertyA;
alert(RP.PropertyA);
delete RP.MethodA;
RP.MethodA();
delete rp.PropertyA;
alert(rp.PropertyA);
delete rp.MethodA;
rp.MethodA();
</script>运行结果再次登场:
A Runtime Error has occurred.
Do you wish to Debug?
Error: Object doesn't support this property or method
10
RP.prototype.MethodA
好玩吧,看出来什么名堂了吗?这里的RP.PropertyA和RP.MethodA只是用来做参照的,可是怎么把this.PropertyA和this.MethodA都delete了,还能出来结果,而且还是prototype导入的属性和方法呢?
这就是JScript的prototype和prototype pattern中prototype最大的不同了,JScript中的这个所谓的prototype属性其实是个语言本身支持的特性,这里没有发生任何的copy,不管shallow还是deep的。对于JScript的解释引擎,它在处理"."或"[keyName]"引用的对象的属性和方法时,先在对象本身的实例(this)中查找,如果找到就返回或执行。如果没有查找到,就查找对象的prototype(this.constructor.prototype)里是否定义了被查找的对象和方法,如果找到就返回或执行,如果没有查找到,就返回undefined(对于属性)或runtime error(对于方法)。
正因为prototype导入类实例的属性或方法是动态查找的,所以我们才能对系统内部对象添加prototype属性和方法,比如给String对象添加trim方法:

<script lanuage="javascript">
String.prototype.trim()

{
return this.replace(/(^\s+)|(\s+$)/g, "");
}
</scritp>显然JScript中的这种用法也是prototype pattern中的prototype不能解释和支持的。
这下对于JScript OOP中原型继承法的理解因该没有任何的障碍了吧?同时也应该明白为什么原型继承法有那么大的天生缺陷了吧?当然如果有任何问题,欢迎继续讨论。
附演示示例源代码:
;
RP.MethodA = function()
{
alert("RP.MethodA ");
};
this.PropertyA = 100;
this.MethodA = function()
{
alert("this.MethodA");
};
}
RP.prototype.PropertyA = 10;
RP.prototype.MethodA = function()

{
alert("RP.prototype.MethodA");
};
</script>
<script language="javascript">
rp = new RP();
delete RP.PropertyA;
alert(RP.PropertyA);
delete RP.MethodA;
RP.MethodA();
delete rp.PropertyA;
alert(rp.PropertyA);
delete rp.MethodA;
rp.MethodA();
</script>
</body>
</html>
The End.
JScript中的prototype(原型)属性研究的更多相关文章
- java基础64 JavaScript中的Arrays数组对象和prototype原型属性(网页知识)
1.Arrays数组对象的创建方式 方式一: var 变量名=new Array(); //创建一个长度为0的数组. 方式二: var 变量名=new Array(长度); //创建一个指定长度的数组 ...
- js中的prototype原型解析
在典型的面向对象的语言中,如java,都存在类(class)的概念,类就是对象的模板,对象就是类的实例.但是在Javascript语言体系中,是不存在类(Class)的概念的,javascript中不 ...
- javascript之prototype原型属性
这个地方有点绕,仔细理解代码的意义. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " ...
- javascript中的prototype(原型)认识
prototype实现了对象与对象的继承,在JS中变量,函数,几乎一切都是对象,而对象又有_ptoro_属性,这个属性就是通常说的原型,是用来指向这个对象的prototype对象,prototype对 ...
- prototype原型属性
<script type="text/javascript"> /* 需求:想把getMax与searchEle方法添加 到数组对象中. functoin Array( ...
- javascript之prototype原型属性案例
练习: 给字符串对象添加一个toCharArray的方法,然后再添加一个reverse(翻转)的 方法 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML ...
- JavaScript OOP(三):prototype原型对象(即构造函数的prototype属性)
通过构造函数生成的实例化对象,无法共享属性或方法(即每个实例化对象上都有构造函数中的属性和方法):造成了一定的资源浪费 function Obj(name,age){ this.name=name; ...
- jQuery原型属性constructor,selector,length,jquery和原型方法size,get,toArray源码分析
首先看一下在jQuery1.7.1中定义的原型属性和方法有哪些? init方法作为实际的构造函数已经详细分析过了,需要了解可以参考http://www.cnblogs.com/yy-hh/p/4492 ...
- javascript的基础知识及面向对象和原型属性
自己总结一下javascript的基础知识,希望对大家有用,也希望大家来拍砖,毕竟是个人的理解啊 1.1 类型检查:typeof(验证数据类型是:string) var num = 123; cons ...
随机推荐
- Jquery基础之动画操作
Jquery的动画效果能够轻松的为网页添加动画效果,为网页带来了新的活力. 一.show()方法和hide()方法 show()方法和hide()方法是jquery中最基本的动画方法.使用show() ...
- adb 异常报错----adb server is out of date. killing... ADB server didn't ACK * failed to start daemon *
在Eclipse进行android开发的时候,由于要启动adb,但有时候其他的程序启动会占用adb程序的端口,这时候在对android程序进行调试的时候就会出现报错: 究其原因就是因为其他程序占用了a ...
- 强烈推荐一款CSS导航菜单
强烈推荐一款CSS导航菜单,用到政府学校类网站上超级不错,有点类似站长网菜单的味道,只不过颜色不一样而已,这种菜单还不是真正意义上的“下拉”菜单,应该叫滑出菜单吧?反正比较不错,不多说了. <! ...
- CSS美化页面滚动条
文章来自:http://www.webhek.com/scrollbar 本文将会告诉你如何用CSS修改/美化浏览器页面上出现的滚动条.改变它们的颜色,调整它们的外形,适配你对页面UI设计.我们首先将 ...
- uva540 Team Queue by sixleaves
这道题目.主要是对队列的灵活应用.其实就是一道模拟题目,只要你洞察出题目的本质就十分简单.题目意思大体是有多组测试数据,每组的一开始是一个数字t,代表一共有多少的团队,接着是t行输入,每一行都由一个数 ...
- 匿名方法和Lambda表达式
匿名方法本质上是一传递给委托的代码块,是使用委托的另一种方法. 规则: 1.匿名方法中不能使用跳转语句跳至次匿名方法的外部,反之亦然:匿名方法外部的跳转语句也不能跳转到匿名方法的内部: 2.在匿名方法 ...
- java 获取特定天数的时间戳
public Timestamp strToDate(int type){ Timestamp time = null; DateFormat format2= new SimpleDateForma ...
- 再议Swift操作符重载
今天我们来谈一谈Swift中的操作 符重载,这一功能非常实用,但是也相当有风险.正所谓“能力越大责任越大”,这句话用来形容操作符重载最合适不过了.它可以令你的代码更加简洁,也可以让 一个函数调用变得又 ...
- 【Android Studio】studio学习系列(一) 从eclipse导入project
Android google官方出的IDE android studio 一直都在走bate版本号,尽管如此,总认为它比ADT更加靠谱.所以我也想用studio来开发滴.可项目一直都是eclipse的 ...
- .NET程序性能优化基本要领
想了解更多关于新的编译器的信息,可以访问 .NET Compiler Platform ("Roslyn") 基本要领 在对.NET 进行性能调优以及开发具有良好响应性的应 ...