Javascript Object.extend


Posted in Javascript onMay 18, 2010

既然是类,那么就有抽象类,具体类,类的继承,同时,类的成员可以有实例成员和静态成员。下面来看一下prototype是怎么做到这些的。
先看prototype中的以下的代码:

var Abstract = new Object(); 
Object.extend = function(destination, source) { 
for (property in source) { 
destination[property] = source[property]; 
} 
return destination; 
} 
Object.prototype.extend = function(object) { 
return Object.extend.apply(this, [this, object]); 
}

第一个声明了一个对象Abstract,Object其实是一个函数,他没有任何成员,所以是一个空类,所以Abstract也就没有任何成员。这个暂时不说,后面可以看到这是抽象类的基础。先解释以下这个语法:
function.member=function(){}
在这种情况下,function一般都是已经定义过的,这条语句的作用是给function增加一个静态成员member,member的内容是等号后面的。如上面第二段代码Object.extend=……,就是给Object这个类增加了一个静态方法extend。ok,我们知道了怎样给一个类定义静态成员,那么你一定很想知道实例成员怎么定义,很简单,在类名和成员名之间加上prototype:
function.prototype.member=function(){}
prototype不仅可以这么使用,还可以:
function.prototype={ 
member1:function(){……}, 
member2:"abc", 
member3:function(){……} 
}

这样就是实现了实例成员的定义。但prototype代表什么意思呢?在第一篇我说过,直接用{}括起来,表示一个对象,如Prototype,Class都是这样定义的全局对象。而看下面一种用法,prototype后面就是一个{}的结构,难道它也是对象?是的,没错,prototype其实也是一个对象!在javascript里,一个对象我们可以任意增加它的成员,用如下的语法:
object.member=function(){……};
只要经过这样的定义,一个对象就可以立刻具有member这个方法!javascript就是这么神奇!
好,我们现在知道了prototype是一个对象,而function是一个函数或者类,那么我们可以认为prototype是任何一个类(函数)都内部保留的一个静态成员。它的功能就是存储这个类的所有成员指针,但这些成员都只是原型,没有经过初始化,这也符合prototype的原义。你可以随时通过prototype这个对象来扩充成员。在new一个类时,prototype的成员就经过初始化,然后赋给了实例化的对象。
上面第三段代码Object.prototype.extend=……,就是给Object增加了一个实例方法extend,实例方法中就可以引用this指针,指向由这个类实例化的对象本身。当然,这个对象就具有成员extend。
继续之前,先了解一下两个语句:
for(var p in object){}
method.apply(object,arguments);
第一句:列举出一个变量的所有成员,如果是函数,那么是所有静态成员;如果是对象,那就是所有实例成员,p的类型是一个字符串。表示成员的名称。引用一个成员不仅可以用variabel.member,还可以用variabel["member"]。反过来,赋值也是如此。这就给枚举一个变量的成员带来了很大方便。
第二条语句:将method这个方法应用到object去执行,参数是arguments这个数组。注意:method并不是object的成员。但是,我们可以认为这条语句执行的意思就是:object.method(arguments)。这是一个很重要的方法,后面会经常用到,你也会逐渐熟悉它的。
下面继续extend,它是一个非常重要的方法,可以看到它既是类Object的静态成员,也是其实例成员,那它有什么作用呢?让我们来看:它接收两个参数,destination和source,如果destination和source都是类,那么它的功能是把类source的所有静态成员都复制给类destination,如果destination和source都是对象,那么是把所有实例成员都复制过来。这时destination中如果已经有同名成员,那么这个成员将被覆盖。也就是说让destination具有了source的所有成员,并且函数返回这个destination。下面看extend作为Object的实例成员:
Object.prototype.extend = function(object) {
return Object.extend.apply(this, [this, object]);
}
开始有点晕了,不过不要急,还是可以看懂的,apply语法刚刚已经讲过了,它的调用者是一个方法,而Object.extend是一个静态方法,它被应用到this上面,也就是Object的实例,假设为obj,后面方括号是一个数组,包括两个成员,this和object。这个数组实际上就是Object静态成员extend的arguments参数。那么这条语句就相当于执行
obj.extend(this,object);
this不解释了,表示本身。object是什么?参数,恩,是实例方法extend传来的参数,不要混淆。extend呢?obj并没有定义extend实例成员,但通过apply,它可以把Object的静态成员extend拿来使用,再看一下extend的函数体:
Object.extend = function(destination, source) {
for (property in source) {
destination[property] = source[property];
}
return destination;
}
因为obj是对象,object也是对象,即destination和source都是对象,于是函数的作用就是使obj具有object的所有成员。并且会返回obj。听起来有点拗口,但逻辑很简单:让obj“继承于”object!很好,我们看到了继承,但你肯定会问,对象的继承,第一次听说啊,我们讲继承都是讲的类的继承。没错,现在的确还没有看到真正的类继承,但已经近在眼前了:类不就是有个prototype吗,而prototype是对象!
好,想到这一点,类的继承语法看似很简单了:
b.prototype.extend(a.prototype);
让b继承a。
可是事实却没那么简单:prototype是存放方法原型指针,extend方法没有初始化,不能使用!要使用extend,就必须实例化一个对象。还是看看prototype是怎么做的吧:
b.prototype=(new a()).extend(b.prototype);
很高明的办法!充分说明了函数其实也是一个变量的道理。先实例化a对象,然后在它基础上调用extend,将所有的成员b.prototype的成员覆盖到a的对象,然后把这个a对象再赋值给b.prototype。完成了b从a继承的工作。在实际使用中,一般的用法都是:
b.prototype=(new a()).extend({});
因为让一个b继承自a,通常b之前都是一个未定义的类,所以后面的{}中其实就可以定义类成员。当然,你也可以先定义,再继承,只是和传统概念有所区别了。
OK,今天写到这里很累了,估计看的人也是,呵呵。现在我们基本明白了prototype的类开发框架,可以看一些高级应用了,下回合再见:)
<script language="javascript"> 
//给Object对象增加静态方法extend,该方法的作为复制source有所有属性和方法到destination 
Object.extend = function(destination, source) { 
for (property in source) { 
destination[property] = source[property]; 
} 
return destination; 
} var dog = function(name) 
{ 
this.name = name; 
} 
//将printName方法复制给dog.prototype 
Object.extend(dog.prototype, 
{ 
printName:function() 
{ 
alert(this.name); 
} 
} 
); 
var a = new dog("dog"); 
a.printName(); 
</script>
Javascript 相关文章推荐
使用jquery插件实现图片延迟加载技术详细说明
Mar 12 Javascript
jQuery实现简单的文件上传进度条效果
Mar 26 Javascript
JavaScript下的时间格式处理函数Date.prototype.format
Jan 27 Javascript
基于jquery实现图片放大功能
May 07 Javascript
JavaScript和jQuery制作光棒效果
Feb 24 Javascript
JS+H5 Canvas实现时钟效果
Jul 20 Javascript
微信小程序入门之广告条实现方法示例
Dec 05 Javascript
利用Dectorator分模块存储Vuex状态的实现
Feb 05 Javascript
详解Vue中使用Axios拦截器
Apr 22 Javascript
layui 实现table翻页滚动条位置保持不变的例子
Sep 05 Javascript
vue实现图片上传预览功能
Dec 23 Javascript
vue抽出组件并传值实例
Jul 31 Javascript
Jsonp 跨域的原理以及Jquery的解决方案
May 18 #Javascript
javascript 密码强度验证规则、打分、验证(给出前端代码,后端代码可根据强度规则翻译)
May 18 #Javascript
JS request函数 用来获取url参数
May 17 #Javascript
asp.net+js 实现无刷新上传解析csv文件的代码
May 17 #Javascript
JQuery中的ready函数冲突的解决方法
May 17 #Javascript
jQuery 学习第七课 扩展jQuery的功能 插件开发
May 17 #Javascript
jQuery 学习第六课 实现一个Ajax的TreeView
May 17 #Javascript
You might like
《PHP边学边教》(04.编写简易的通讯录――视频教程1)
2006/12/13 PHP
PHP连接SQLSERVER 注意事项(附dll文件下载)
2012/06/28 PHP
PHP中header函数的用法及其注意事项详解
2016/06/13 PHP
php实现xml与json之间的相互转换功能实例
2016/07/07 PHP
让JavaScript 轻松支持函数重载 (Part 1 - 设计)
2009/08/04 Javascript
JavaScript动态调整TextArea高度的代码
2010/12/28 Javascript
JS获取下拉列表所选中的TEXT和Value的实现代码
2014/01/11 Javascript
获取select元素被选中的文本内容的js代码
2014/01/29 Javascript
jquery向上向下取整适合分页查询
2014/09/06 Javascript
jQuery解析XML文件同时动态增加js文件的方法
2015/06/01 Javascript
Hallo.js基于jQuery UI所见即所得的Web编辑器
2016/01/26 Javascript
JavaScript中return用法示例
2016/11/29 Javascript
详解微信小程序 通过控制CSS实现view隐藏与显示
2017/05/24 Javascript
微信分享调用jssdk实例
2017/06/08 Javascript
轻松搞定jQuery+JSONP跨域请求的解决方案
2018/03/06 jQuery
.vue文件 加scoped 样式不起作用的解决方法
2018/05/28 Javascript
Angularjs中的$apply及优化使用详解
2018/07/02 Javascript
JavaScript监听键盘事件代码实现
2020/06/03 Javascript
python高并发异步服务器核心库forkcore使用方法
2013/11/26 Python
Tornado高并发处理方法实例代码
2018/01/15 Python
Python3中正则模块re.compile、re.match及re.search函数用法详解
2018/06/11 Python
django中使用事务及接入支付宝支付功能
2019/09/15 Python
解决pycharm最左侧Tool Buttons显示不全的问题
2019/12/17 Python
Python模块的定义,模块的导入,__name__用法实例分析
2020/01/07 Python
解决pyinstaller 打包exe文件太大,用pipenv 缩小exe的问题
2020/07/13 Python
css3实现波纹特效、H5实现动态波浪效果
2018/01/31 HTML / CSS
巴西电子、家电、智能手机购物网站:Girafa
2019/06/04 全球购物
Urban Decay官方网站:美国化妆品品牌
2020/06/04 全球购物
亚洲领先的设计购物网站:Pinkoi
2020/11/26 全球购物
英文简历自荐信范文
2013/12/11 职场文书
申请任职学生会干部自荐书范文
2014/02/13 职场文书
《大自然的语言》教学反思
2014/04/08 职场文书
目标责任书格式范文
2015/05/11 职场文书
python获取对象信息的实例详解
2021/07/07 Python
SSM VUE Axios详解
2021/10/05 Vue.js
MySQL视图概念以及相关应用
2022/04/19 MySQL