javascript中的prototype属性使用说明(函数功能扩展)


Posted in Javascript onAugust 16, 2010

这是一个比较特殊的属性,Javascript中的继承一般都依赖这属性实现。
在Javascript中,一切都是对象,字符串是对象,数组是对象,变量是对象,函数也是对象,所以才会允许['a','b','c'].push('d');这样的操作存在。类本身也是一个对象,也可以定义属性和方法:

function Test(){}; 
Test.str = 'str'; 
Test.fun = function(){return 'fun';}; 
var r1 = Test.str; // str 
var r2 = Test.fun(); // fun 
var inst = new Test(); 
var r3 = inst.str; // undefined 
var r4 = inst.fun(); // undefined

prototype就是一个作用于类的属性。默认情况下,所有Javascript类都会有一个prototype属性,但是类实例没有。
function Test(){}; 
var p1 = typeof(String.prototype); // object 
var p2 = typeof(Test.prototype); // object 
var p3 = typeof(new Test().prototype); // undefined 
var p4 = typeof(Object.prototype); // object 
var p5 = typeof(new Object().prototype); // undefined

取值与赋值
在Javascript中,当我们取一个对象中并不存在的属性或是方法时,它会试图查看该对象所对应的类中的prototype属性中是否包含该属性或是方法,而prototype也是一个Javascript对象,若是其中也没有,该prototype又会访问它对应的类的prototype,如此一级级地向上访问,直到找到需要的属性或方法,或是prototype属性为null。
function Test(){}; 
Test.test = 'str'; 
function pt1() 
{ this.test1 = 'pt1'; }; 
function pt2() 
{ this.test2 = 'pt2'; }; 
pt2.prototype.test3 = 'test3'; 
pt2.prototype.test1 = 'test4'; 
pt1.prototype = new pt2(); 
Test.prototype = new pt1(); 
var inst = new Test(); 
var p1 = inst.test; // undefined 
var p2 = inst.test1; // pt1 而不是 test4 
var p3 = inst.test2; // pt2 
var p4 = inst.test3; // test3

相对于取值,赋值就简单得多了。它并不会一层层向上查找prototype中的属性值,而直接对当前的实例进行赋值,没有则创建。
内置类的增强
在Javascript中并不能直接修改内置类的prototype。但是可以通过修改prototype的属性达到修改内置类行为的目的。
Array.prototype = {push:function(){alert('test1');}}; // 不起作用 
Array.prototype.push = function(){alert('test2');}; // 可以 
var test = new Array('a','b','c'); 
test.push('d'); // test2

一次可以插入多个元素的Array.push函数:
Array.prototype.pushs = function() 
{ 
var pos = this.length; 
for(var i=0; i<arguments.length; i++) 
{ 
this[++pos] = arguments[i]; 
} 
return this.length; 
} 
var test = new Array('a','b','c'); 
test.pushs('d','e');

值得注意的是,为内置类的prototype添加的函数,在使用for语句输出属性时,也会被显示:
var str; 
for(var i in test) 
{ 
str += (' ' + i); // '0 1 2 3 4 5 pushs' pushs自定义函数。 
}

但是可以通过hasOwnProperty()进行判断:
var str; 
for(var i in test) 
{ 
if(test.hasOwnProperty(i)) // 过滤掉pushs函数。 
{ str += (' ' + i); } 
}
]
一点点注意事项
前面说过,prototype是类的一个属性。更改prototype中的属性值,有可能会带来意想不到的灾难!
function Test(){} 
Test.prototype.num = 3; 
var inst1 = new Test(); 
var inst2 = new Test(); 
Test.prototype.num = 4; // 所有指向Test.prototype.num的值。 
var p1 = inst1.num; // 4 
var p2 = inst2.num; // 4 
inst1.num = 5; // 赋值,会为inst对象创建一个num属性。 
Test.prototype.num = 6; // 所有指向Test.prototype.num的值。 
var p3 = inst1.num; // 5 这里返回的是刚创建的inst1.num的值,而不是Test.prototype.num的值。 
var p4 = inst2.num; // 6 
delete Test.prototype.num; 
var p5 = inst1.num; // 5 inst1.num依然存在。 
var p6 = inst2.num; // undefined Test.prototype.num 被删除了。
Javascript 相关文章推荐
jQuery select操作控制方法小结
May 26 Javascript
javascript 函数参数限制说明
Nov 19 Javascript
Jquery中对数组的操作代码
Aug 12 Javascript
JS:window.onload的使用介绍
Nov 13 Javascript
js中传递特殊字符(+,&amp;)的方法
Jan 16 Javascript
jQuery实现自定义下拉列表
Jan 05 Javascript
实现前后端数据交互方法汇总
Apr 07 Javascript
浅谈Javascript实现继承的方法
Jul 06 Javascript
手淘flexible.js框架使用和源代码讲解小结
Oct 15 Javascript
js实现简单分页导航栏效果
Jun 28 Javascript
从零撸一个pc端vue的ui组件库( 计数器组件 )
Aug 08 Javascript
JavaScript实现前端倒计时效果
Feb 09 Javascript
javascript下高性能字符串连接StringBuffer类
Aug 16 #Javascript
子窗口、父窗口和Silverlight之间的相互调用
Aug 16 #Javascript
为JavaScript提供睡眠功能(sleep) 自编译JS引擎
Aug 16 #Javascript
JavaScript实用技巧(一)
Aug 16 #Javascript
IE6下js通过css隐藏select的一个bug
Aug 16 #Javascript
新手常遇到的一些jquery问题整理
Aug 16 #Javascript
使用jQuery轻松实现Ajax的实例代码
Aug 16 #Javascript
You might like
Yii入门教程之目录结构、入口文件及路由设置
2014/11/25 PHP
PHP getallheaders无法获取自定义头(headers)的问题
2016/03/23 PHP
DHTML 中的绝对定位
2006/11/26 Javascript
js防止表单重复提交实现代码
2012/09/05 Javascript
Javascript继承(上)——对象构建介绍
2012/11/08 Javascript
JQUERY实现左侧TIPS滑进滑出效果示例
2013/06/27 Javascript
基于BootStrap环境写jQuery tabs插件
2016/07/12 Javascript
Node+Express+MongoDB实现登录注册功能实例
2017/04/23 Javascript
深入剖析Express cookie-parser中间件实现示例
2018/02/01 Javascript
angularJs select绑定的model取不到值的解决方法
2018/10/08 Javascript
浅谈Vue.js 中的 v-on 事件指令的使用
2018/11/25 Javascript
Vue.Draggable拖拽功能的配置使用方法
2020/07/29 Javascript
详解Vue-Router源码分析路由实现原理
2019/05/15 Javascript
基于JS实现数字动态变化显示效果附源码
2019/07/18 Javascript
npm全局环境变量配置详解
2020/12/15 Javascript
flask入门之文件上传与邮件发送示例
2018/07/18 Python
python3去掉string中的标点符号方法
2019/01/22 Python
Python考拉兹猜想输出序列代码实践
2019/07/05 Python
python Elasticsearch索引建立和数据的上传详解
2019/08/04 Python
python+selenium 点击单选框-radio的实现方法
2019/09/03 Python
python3.7将代码打包成exe程序并添加图标的方法
2019/10/11 Python
python的等深分箱实例
2019/11/22 Python
计算pytorch标准化(Normalize)所需要数据集的均值和方差实例
2020/01/15 Python
django3.02模板中的超链接配置实例代码
2020/02/04 Python
CSS3 @keyframes简单动画实现
2018/02/24 HTML / CSS
中国旅游网站:同程旅游
2016/09/11 全球购物
Dower & Hall官网:英国小众轻奢珠宝品牌
2019/01/31 全球购物
大四毕业生学习总结的自我评价
2013/10/31 职场文书
小学红领巾中秋节广播稿
2014/01/13 职场文书
《藏戏》教学反思
2014/02/11 职场文书
股东合作协议书范本
2014/04/14 职场文书
普通党员对照检查材料
2014/08/28 职场文书
迟到检讨书2000字(精选篇)
2014/10/07 职场文书
个人培训总结
2015/03/05 职场文书
Springboot/Springcloud项目集成redis进行存取的过程解析
2021/12/04 Redis
win10滚动条自动往上跑怎么办?win10滚动条自动往上跑的解决方法
2022/08/05 数码科技