zoukankan      html  css  js  c++  java
  • javascript 中关于call方法的详解。

      

         关于javascript中的call方法,网上查了一些资料总是不得详解。总结网上的观点,call有两个妙用:

                          1: 继承。(不太喜欢这种继承方式。)

                          2: 修改函数运行时的this指针。

         js中关于call的解释如下:

                        

                              js关于call的这份文档容易让人迷糊。而《javascript权威指南》对call的描述就比较容易理解了。

                                       

                               

                              注意红色框中的部分,f.call(o)其原理就是先通过 o.m = f 将 f作为o的某个临时属性m存储,然后执行m,执行完毕后将m属性删除。

                              如 function f(){

                                                      var a = "name";

                                                      this.b = "test1";

                                                      this.add = function (){ return "add" }

                                           }

                                   function o(){

                                                    this. c = "c";  

                                           }

                                   f.all(o);

                                                                  图  1

                                 图1中 f.call(o)其实相当于: function o(){ 

                                                                          this.c = "c" ;                                                          

                                                                          var a = "name";

                                                                          this.b = "test1";

                                                                          this.add = function (){ return "add" }

                                                              }

                                 说白了,就是把f的方法在o中走一遍,但不做保存。既然不做保存,那么如何通过call实现继承和修改函数运行时的this指针等妙用?关键在于this,对,关键还是在于this的作用域。在之前的文章反复说过,this的作用域不是定义它的函数的作用域,而是执行时的作用域。

                                  如下例子:

                                             

                                                                                图     2

                                   如图2, 在执行A.call(this)之前,输出的this 不包含任何属性和方法,之后则继承了A的属性和方法。还是按照上面的方法解释,执行完A.call(this) (this此时代表执行时的作用域,即B)后,B构造函数如下:

                                         function B()

                                           {

                                              console.log(this);                                        

                                              this.test1 = "test1";

                                              this.test2 = "test2";

                                              this.add = function(){ return this.test1 + this.test2 ; }

                                               console.log(this); 

                                            }

                                       因为调用A.call(this)的时候,this作用域已经发生改变了,代表的都是B(),哪怕执行A中的方法和属性的时候,this也是代表着执行时的作用域B();所以如此才能实现继承,即将A()中的属性赋值和方法定义在B()中再走一遍。其实此时也修改了函数运行时的this指针。

                                        关于call的第二个妙用,修改函数运行时的this指针:

                                            这里采用一位贴吧大神的回答,做了一个测试例子,其实应该也是js中关于each遍历的定义。

                                             

                                                                                              图             3

                                           如图3,第一个中直接调用fn方法,其中因为没有定义函数作用域,输出的this表示window对象,即全局对象。而第二个中通过fn.call(array[index]  , index , array[index] )将fn方法放到array[index]作用域中执行,输出的this表示的是array[index]对象。

                                          换一个视角:

                                                  

                                                                                图   4

                                           如图 4 , 通过each方法中调用call方法可以实现遍历。我们假设array[index]是DOM元素集合,如标签为li的所有集合,假设fn是我们自定义实现的方法,不就是我们用的each遍历DOM元素的方法吗?

                                           

                                           

                                                                                   图               5

                                               如图5,简单的代码即实现了遍历DOM元素的each方法。

  • 相关阅读:
    Spring MVC Ajax 嵌套表单数据的提交
    Spring MVC 过滤静态资源访问
    Spring MVC 页面跳转时传递参数
    IDEA Maven 三层架构 2、运行 springMVC
    IDEA Maven 三层架构 1、基本的Archetype 搭建
    EasyUI DataGrid 基于 Ajax 自定义取值(loadData)
    Spring MVC Ajax 复杂参数的批量传递
    Mybatis Sql片段的应用
    在 Tomcat 8 部署多端口项目
    自动升级的设计思路与实现
  • 原文地址:https://www.cnblogs.com/f-dream/p/4950918.html
Copyright © 2011-2022 走看看