JS面向对象、prototype、call()、apply()


Posted in Javascript onMay 14, 2009

一、 起因
那天用到prototype.js于是打开看看,才看几行就满头雾水,原因是对js的面向对象不是很熟悉,于是百度+google了一把,最后终于算小有收获,写此纪念一下^_^。
prototype.js代码片段

var Class = { 
create: function() { 
return function() { 
this.initialize.apply(this , arguments); 
} 
} 
} 
// Class使用方法如下 
var A = Class.create(); 
A. prototype={ 
initialize:function(v){ 
this .value=v; 
} 
showValue:function(){ 
alert(this.value); 
} 
} 
var a = new A(‘helloWord!'); 
a. showValue();//弹出对话框helloWord!

l initialize是什么?
l apply方法是干什么的?
l arguments变量呢?
l 为什么new A后就会执行initialize方法?
寻找答案:
二、 Js的面向对象
initialize是什么?
只不过是个变量,代表一个方法,用途是类的构造函数。
其具体功能靠js的面向对象支持,那么js的面向对象是什么样子的那?和java 的有什么相同与不同?
看代码:
var ClassName = function(v){ 
this.value=v; 
this.getValue=function(){ 
return this.value; 
} 
this.setValue=function(v){ 
this.value=v; 
} 
}

那么JS中的函数和类有什么不同呢?
其实是一样的,ClassName就是一个函数,当出现在new后面的时候就作为一个构造函数来构造对象。

var objectName1 = new ClassName(“a”);//得到一个对象

其中objectName1就是执行ClassName构造函数后得到的对象,而在ClassName函数中的this指的就是new之后构造出来的对象,所以objectName1会后一个属性和两个方法。可以通过这样来调用他们:
objectName1.setValue(''hello''); 
alert(objectName1.getValue());//对话框hello 
alert(objectName1.value) ;//对话框hello

那么
var objectName2 = ClassName(“b”);//得到一个对象

这样objectName2得到的是什么呢?显然是方法的返回值,这里ClassName只作为了一个普通的函数(虽然首字母大写了)。但是在之前写的ClassName中并没有返回值,所以objectName2会是undifinded那么“b”赋给谁了呢?在这并没有产生一个对象,而只是单纯的执行这个方法,所以这个“b”赋值给了调用这个方法的对象window,证据如下:
var objectName2 = ClassName(“b”);//得到一个对象
alert(window.value);//对话框b
所以JS中的所有function都是一样的,但是用途可能是不同的(用作构造对象抑或是执行一个过程)。
下面该回到主题了initialize是干什么的?
var Class = { 
create: function() { 
return function() { 
this.initialize.apply(this , arguments); 
} 
} 
} 
var A = Class.create();

这段代码是构造个一个function复制给A,这个function是
function() { 
this.initialize.apply(this , arguments); 
}

并且后面这个方法是用来做构造函数的。当使用这个构造函数来构造对象的时候,会让构造出来的这个对象的initialize变量执行apply()方法,apply()的用途后面在说,继续说initialize。这样在初始化对象的时候会联系到initialize(怎么联系就要看apply的了)。
那么
A.prototype={ 
initialize:function(v){ 
this .value=v; 
} 
showValue:function(){ 
alert(this.value); 
} 
}

是什么意思呢?
Prototype是“原型”的意思。A是一个function(),那么A. prototype,就是function中的一个变量,其实是个对象。这个对象拥有什么方法,那么function产生的对象就拥有什么方法,故
var a = new A(‘helloWord!');
a. showValue();//弹出对话框helloWord!
所以a对象也会有initialize方法,不只如此,每一个有A构造出来的对象都会有一个initialize方法,而在前面说过,构造的时候会调用构造函数,构造函数里面会让initialize去调用apply方法,于是在new A(‘helloWord!')的时候initialize回去调用apply方法。这也就是调用了一个初始化的方法。
三、 call()和apply()
下面开始研究apply(),在网上找了几个资料,并结合自己的研究,了解了call()和apply()的功能。功能基本一样,function().call(object,{},{}……)或者function().apply (object,[……])的功能就是对象object调用这里的funciton(),不同之处是call参数从第二个开始都是传递给funciton的,可以依次罗列用“,”隔开。而apply只有两个参数,第二个是一个数组,其中存储了所有传递给function的参数。
this.initialize.apply(this , arguments);
是什么意思?
这里的第一个this,是指用new调用构造函数之后生成的对象,也就是前面的a,那么第二个this也当然应该是指同一个对象。那这句话就是this(也就是a)调用initialize方法,参数是arguments对象(参数的数组对象),所以在构造函数执行的时候,对象a就会去执行initialize方法来初始化,这样就和单词“initialize”的意思对上了。
那么执行initialize方法的参数怎么传递进去的呢?
四、 Arguments对象
这段代码能说明一切了:
function test(){ 
alert(typeof arguments); 
for(var i=0; i<arguments.length; i++){ 
alert(arguments[i]); 
} 
} 
test("1","2","3"); 
test("a","b");

执行后alert(typeof arguments);会显示object,说明arguments是对象。然后会依次打出1、2、3。说明arguments就是调用函数的实参数组。
var Class = { 
create: function() { 
return function() { 
this.initialize.apply(this , arguments); 
} 
} 
}

arguments 就是create返回的构造函数的实参数组,那么在
var a = new A(‘helloWord!');
的时候‘helloWord!'就是实参数组(虽然只有一个字符串),传递给方法apply,然后在调用initialize 的时候作为参数传递给初始化函数initialize。
Javascript 相关文章推荐
Chrome中模态对话框showModalDialog返回值问题的解决方法
May 25 Javascript
javascript动态的改变IFrame的高度实现自动伸展
Oct 12 Javascript
JavaScript采用递归算法计算阶乘实例
Aug 04 Javascript
在JavaScript中使用JSON数据
Feb 15 Javascript
Jquery实现的简单轮播效果【附实例】
Apr 19 Javascript
vue.js通过自定义指令实现数据拉取更新的实现方法
Oct 18 Javascript
jq源码解析之绑在$,jQuery上面的方法(实例讲解)
Oct 13 jQuery
vue中v-model的应用及使用详解
Jun 27 Javascript
Angular6 发送手机验证码按钮倒计时效果实现方法
Jan 08 Javascript
js设置默认时间跨度过程详解
Jul 17 Javascript
layer.alert回调函数执行关闭弹窗的实例
Sep 11 Javascript
JS 设计模式之:单例模式定义与实现方法浅析
May 06 Javascript
JavaScript Date对象使用总结
May 14 #Javascript
jQuery 技巧大全(新手入门篇)
May 12 #Javascript
JS 字符串连接[性能比较]
May 10 #Javascript
javascript获取当前ip的代码
May 10 #Javascript
&amp;lt;script defer&amp;gt; defer 是什么意思
May 10 #Javascript
extjs fckeditor集成代码
May 10 #Javascript
一组JS创建和操作表格的函数集合
May 07 #Javascript
You might like
深入解析PHP中foreach语句控制数组循环的用法
2015/11/30 PHP
thinkPHP+phpexcel实现excel报表输出功能示例
2017/06/06 PHP
PHP实现批量重命名某个文件夹下所有文件的方法
2017/09/04 PHP
PHP实现 APP端微信支付功能
2018/06/22 PHP
PHP PDO和消息队列的个人理解与应用实例分析
2019/11/25 PHP
VBScript版代码高亮
2006/06/26 Javascript
jquery form表单提交插件asp.net后台中文解码
2010/06/12 Javascript
扩展easyui.datagrid,添加数据loading遮罩效果代码
2010/11/02 Javascript
微信小程序 教程之数据绑定
2016/10/18 Javascript
jQuery实现在新增加的元素上添加事件方法案例分析
2017/02/09 Javascript
原生js实现密码输入框值的显示隐藏
2017/07/17 Javascript
JS实现微信摇一摇原理解析
2017/07/22 Javascript
vuex中使用对象展开运算符的示例
2017/09/25 Javascript
vue 引入公共css文件的简单方法(推荐)
2018/01/20 Javascript
详解JQuery基础动画操作
2019/04/12 jQuery
vue从后台渲染文章列表以及根据id跳转文章详情详解
2020/12/14 Vue.js
[58:29]DOTA2-DPC中国联赛 正赛 Phoenix vs XG BO3 第一场 1月31日
2021/03/11 DOTA
Python中使用PyQt把网页转换成PDF操作代码实例
2015/04/23 Python
让Python代码更快运行的5种方法
2015/06/21 Python
Python嵌套列表转一维的方法(压平嵌套列表)
2018/07/03 Python
使用pyecharts生成Echarts网页的实例
2019/08/12 Python
Python 爬取必应壁纸的实例讲解
2020/02/24 Python
Python 开发工具PyCharm安装教程图文详解(新手必看)
2020/02/28 Python
Python爬虫实现模拟点击动态页面
2020/03/05 Python
浅谈OpenCV中的新函数connectedComponentsWithStats用法
2020/07/05 Python
Cocopanda波兰:购买化妆品、护肤品、护发和香水
2020/05/25 全球购物
请写出 BOOL flag 与"零值"比较的 if 语句
2016/02/29 面试题
学雷锋志愿服务月活动总结
2014/03/09 职场文书
委托书样本
2014/04/02 职场文书
文明城市创建标语
2014/06/16 职场文书
购房意向书
2014/08/30 职场文书
青春飞扬演讲稿
2014/09/11 职场文书
2014年销售人员工作总结
2014/11/27 职场文书
导游词之重庆钓鱼城
2019/09/19 职场文书
JS中如何优雅的使用async await详解
2021/10/05 Javascript
Redis超详细讲解高可用主从复制基础与哨兵模式方案
2022/04/07 Redis