源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

js中call与apply的用法小结

  • 时间:2020-10-04 13:58 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:js中call与apply的用法小结
前天去面试,有个gg问了一些js知识,其中有一道call与apply用法的题目,尽管在365天前用过call方法,但当时还是没能答上来,今天深入总结一下 call和apply,它们的作用都是将函数绑定到另外一个对象上去运行 [b]两者的格式和参数定义:[/b] call( thisArg [,arg1,arg2,… ] );       // 参数列表,arg1,arg2,... apply(thisArg [,argArray] );                 // 参数数组,argArray 上面两个函数内部的this指针,都会被赋值为thisArg,这可实现将函数作为另外一个对象的方法运行的目的 [b]一、call 的简单用法[/b] 首先,我们先看个简单的例子(call):
[u]复制代码[/u] 代码如下:
<!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>
[b]然后,运行结果如下:[/b] global var global var member var input text func func2 测试环境:Google Chrome 10.0.648.45 [b]最后,分析结果[/b] 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 [b] [/b] [b]二、call 继承用法与改进[/b] [b]js使用call模拟继承[/b] [b]测试代码: [/b]
[u]复制代码[/u] 代码如下:
<!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>
[b]运行结果如下:[/b] baseB member baseB member 测试环境:Google Chrome 10.0.648.45 [b]结果分析:[/b] 预期的结果,应该是输出 baseA member 和 baseB member,但实际输出却是 baseB member 和 baseB member (已在IE9、8、6,Maxthon、Chrome、FF、Opera、Safari、360等浏览器测试过,结果都是后者:baseB member) 至此,机器是不会错的,这就需要我们深入分析 我们可能会很容易想到是this引起的,this两次都指向了baseB对象,但是推测真是这样吗? 为了探究实质,我们借助chrome浏览器的调试工具,下断点,进行调试,结果发现: [img]http://files.jb51.net/file_images/article/201312/20131228100214.png[/img] 当调用extend.showSelfA();时,此时的this指向extendAB(并不是我们推测的两次都指向baseB对象 真实原因是extendAB对象的成员变量member在被baseB.call(this);实例化时,被baseB的成员member覆盖了,即extendAB的成员member由baseA member赋值成了baseB member 当然,我们也可以对上面baseA代码稍作修改,来验证我们调试分析的正确性:
[u]复制代码[/u] 代码如下:
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调试信息也验证了我们的正确性: [img]http://files.jb51.net/file_images/article/201312/20131228100420.png[/img] [b]继承改进(prototype)[/b] 以上模拟继承方法,仔细分析不是最好的。 因为每次在函数(类)中定义了成员方法,都会导致实例有副本,因此可以借助prototype原型,进行改进 改进举例如下:
[u]复制代码[/u] 代码如下:
<!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
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部