call和apply,它们的作用都是将函数绑定到另外一个对象上去运行
两者的格式和参数定义:
call( thisArg [,arg1,arg2,… ] ); // 参数列表,arg1,arg2,...
apply(thisArg [,argArray] ); // 参数数组,argArray
上面两个函数内部的this指针,都会被赋值为thisArg,这可实现将函数作为另外一个对象的方法运行的目的 一、call 的简单用法
首先,我们先看个简单的例子(call):
[html] view plaincopyprint?
<!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 var
gFunc.call(window); // show gFunc, global var
gFunc.call(new mFunc()); // show mFunc, member var
gFunc.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 var
global var
member var
input text
func
func2
测试环境:Google Chrome 10.0.648.45
最后,分析结果
、全局对象window调用函数gFunc,this指向window对象,因此this.value为global var
、函数gFunc调用call方法,this默认指向第一个参数window对象,因此this.value也为global var
、函数gFunc调用call方法,this默认指向第一个参数new mFunc(),即mFunc的对象,因此this.value为mFunc的成员变量member var
、函数gFunc调用call方法,this默认指向第一个参数input text控件,即id=‘idTxt’的控件,因此this.value为input控件的value值input text
、函数func2调用call方法,this默认指向第一个参数func函数对象,因此this.value为this.a,即func
、函数func2调用call方法,第二个参数属于函数对象func2的参数,因此alert(x)为第二个参数func2 二、call 继承用法与改进
js使用call模拟继承
测试代码:
[html] view plaincopyprint?
<!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 A
baseB.call(this); // call for B
} window.onload = function()
{
var extend = new extendAB();
extend.showSelfA(); // show A
extend.showSelfB(); // show B
}
</script>
</body>
</html>
运行结果如下:
baseB member
baseB member
测试环境:Google Chrome 10.0.648.45
结果分析:
预期的结果,应该是输出 baseA member 和 baseB member,但实际输出却是 baseB member 和 baseB member
(已在IE9、、,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原型,进行改进
改进举例如下:
[html] view plaincopyprint?
<!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 Person
Person.prototype = { // prototype initialize
initialize: function(obj1, obj2)
{
this.obj1 = obj1;
this.obj2 = obj2;
},
showSelf: function()
{
alert("obj: " + this.obj1 + " and " + this.obj2);
}
} // instance Class
var person = new Person("man", "women"); // two params
person.showSelf(); // show person
</script>
</body>
</html>
运行结果如下:
obj: man and women

最新文章

  1. jQuery最佳编程实践
  2. Neutron分析(1)——简介
  3. java第二课:运算符和表达式
  4. 过滤网页中HTML代码的ASP函数
  5. 【转】android的startActivityForResult学习心得
  6. Linux操作系统分析 ------------------中国科技大学
  7. Xcode5 配置 github
  8. Cocos2d-x 学习之路------(CCCallfunc 系列)
  9. SqLite 使用 Dapper 查询INTEGER类型的主键问题
  10. Jsp中使用数据库连接池.
  11. 了解OutOfMemoryError异常 - 深入Java虚拟机读后总结
  12. 深刻理解iosBlock
  13. lsyncd+rsync配置图片资源双向同步
  14. Python正则替换字符串函数re.sub用法示例(1)
  15. redis 部分操作
  16. Zookeeper入门(四)之Leader选举
  17. scrapy-scrapy如何打开页面?[转]
  18. Vue.js 计算属性是什么
  19. 洛谷 P1171 售货员的难题 【状压dp】
  20. 【BZOJ】1631: [Usaco2007 Feb]Cow Party(dijkstra)

热门文章

  1. GNU Emacs命令速查表
  2. oracle clob blob dblink
  3. MT【186】四边形中的余弦定理
  4. 5月14日 绿城育华NOIP巨石杯试卷解析
  5. 洛谷 T28312 相对分子质量【2018 6月月赛 T2】 解题报告
  6. 《剑指offer》— JavaScript(30)连续子数组的最大和
  7. pthread_detach
  8. UnicodeDecodeError gbk codec can&#39;t decode byte in position illegal multibyte sequence
  9. 通达信zig函数的python实现
  10. PHP 设计模式 单例模式 工厂模式 注册模式