js中call与apply用法
来源:互联网 发布:义隆单片机型号 编辑:程序博客网 时间:2024/06/06 15:00
call和apply,它们的作用都是将函数绑定到另外一个对象上去运行
两者的格式和参数定义:
call( thisArg [,arg1,arg2,… ] ); // 参数列表,arg1,arg2,...
apply(thisArg [,argArray] ); // 参数数组,argArray
上面两个函数内部的this指针,都会被赋值为thisArg,这可实现将函数作为另外一个对象的方法运行的目的一、call 的简单用法
首先,我们先看个简单的例子(call):
<!doctype html><html><head><title> call-apply </title></head><body><input type="text" id="idTxt" value="input text"><script type="text/javascript">var value = "global var";function mFunc(){this.value = "member var";}function gFunc(){alert(this.value);}window.gFunc();// show gFunc, global vargFunc.call(window);// show gFunc, global vargFunc.call(new mFunc());// show mFunc, member vargFunc.call(document.getElementById('idTxt'));// show element, input text</script><script language="javascript">var func = new function(){this.a = "func";}var func2 = function(x){var a = "func2";alert(this.a);alert(x);}func2.call(func, "func2");// show func and func2</script></body></html>
然后,运行结果如下:
global varglobal var
member var
input text
func
func2
测试环境:Google Chrome 10.0.648.45
最后,分析结果
1、全局对象window调用函数gFunc,this指向window对象,因此this.value为global var
2、函数gFunc调用call方法,this默认指向第一个参数window对象,因此this.value也为global var
3、函数gFunc调用call方法,this默认指向第一个参数new mFunc(),即mFunc的对象,因此this.value为mFunc的成员变量member var
4、函数gFunc调用call方法,this默认指向第一个参数input text控件,即id=‘idTxt’的控件,因此this.value为input控件的value值input text
5、函数func2调用call方法,this默认指向第一个参数func函数对象,因此this.value为this.a,即func
6、函数func2调用call方法,第二个参数属于函数对象func2的参数,因此alert(x)为第二个参数func2
二、call 继承用法与改进
js使用call模拟继承
测试代码:
<!doctype html><html><head><title> call - apply for inherit </title></head><body><script type="text/javascript">function baseA()// base Class A{this.member = "baseA member";this.showSelfA = function(){window.alert(this.member);}}function baseB()// base Class B{this.member = "baseB member";this.showSelfB = function(){window.alert(this.member);}}function extendAB()// Inherit Class from A and B{baseA.call(this);// call for AbaseB.call(this);// call for B}window.onload = function(){var extend = new extendAB();extend.showSelfA();// show Aextend.showSelfB();// show B}</script></body></html>
测试环境:Google Chrome 10.0.648.45
结果分析:
预期的结果,应该是输出 baseA member 和 baseB member,但实际输出却是 baseB member 和 baseB member
(已在IE9、8、6,Maxthon、Chrome、FF、Opera、Safari、360等浏览器测试过,结果都是后者:baseB member)
至此,机器是不会错的,这就需要我们深入分析
我们可能会很容易想到是this引起的,this两次都指向了baseB对象,但是推测真是这样吗?
为了探究实质,我们借助chrome浏览器的调试工具,下断点,进行调试,结果发现:
当调用extend.showSelfA();时,此时的this指向extendAB(并不是我们推测的两次都指向baseB对象)
真实原因是extendAB对象的成员变量member在被baseB.call(this);实例化时,被baseB的成员member覆盖了,
即extendAB的成员member由baseA member赋值成了baseB member
当然,我们也可以对上面baseA代码稍作修改,来验证我们调试分析的正确性:
function baseA()// base Class A
{
this.memberA = "baseA member"; // member改成memberA,以区分baseB中的member
this.showSelfA = function()
{
window.alert(this.memberA); // 显示memberA
}
}
再次运行chrome等浏览器,结果如下:
baseA member
baseB member结果和我们的预期相同,同时chrome调试信息也验证了我们的正确性:
继承改进(prototype)
以上模拟继承方法,仔细分析不是最好的。
因为每次在函数(类)中定义了成员方法,都会导致实例有副本,因此可以借助prototype原型,进行改进
改进举例如下:
<!doctype html><html><head><title> call - apply for prototype </title></head><body><script type="text/javascript">var Class = {create: function()// create Function{return function(){this.initialize.apply(this, arguments);}}};var Person = Class.create();// Create Class PersonPerson.prototype = {// prototype initializeinitialize: function(obj1, obj2){this.obj1 = obj1;this.obj2 = obj2;},showSelf: function(){alert("obj: " + this.obj1 + " and " + this.obj2);}}// instance Classvar person = new Person("man", "women");// two paramsperson.showSelf();// show person</script></body></html>运行结果如下:
obj: man and women
- js中call与apply用法
- JS中apply与call的用法
- js中call与apply用法
- JS中apply与call的用法
- JS中apply与call的用法
- js中call与apply用法
- js中call与apply用法
- js中call与apply用法
- js中call与apply用法
- js中call与apply用法
- js中call与apply的用法
- js中call()与apply()的用法
- js中call与apply用法
- Js中apply与call的区别与用法
- js中call与apply的用法小结
- js中的call与apply用法
- js中的apply与call的用法
- js中call和apply的用法
- linux 页表
- 1、Alfresco 4.2.c开发环境的搭建-- alfresco 开发系列
- 编码问题
- 问题十五:定义一个结构体变量(包括年、月、日),输入两个人的生日,求出他们相差多少天。
- Ruby on Rails Resource
- js中call与apply用法
- 微软实习生笔试总结:
- 二分快速幂
- OpenCV中一个窗口显示两幅图像
- Android TextView支持拷贝&粘帖 textIsSelectable
- 高校应届毕业生“IT业”收入最高,Android技术最热门
- l love you
- rdesktop连接windows
- 使BOS支持元数据的热部署