zoukankan      html  css  js  c++  java
  • 说说函数调用模式

      相信大家都知道,函数的调用模式与进入函数执行上下文的this指针有着密不可分的关系。随着调用模式的不同,this指针的指向便有所不同。随着应用的复杂、代码的累积,对于函数作用域的分析真是个头痛的问题。因此,深入理解函数调用模式对函数作用域(this指针)的影响变得至关重要。

    /**
     * 函数调用模式
     * 
     *     1>方法调用模式
     *         (1)当一个函数被保存为对象的一个属性时,称它为一个方法。
     *         (2)当一个调用表达式包含一个属性存取表达式(即一个.表达式或[subscript]下标表达式),
     *             那么它被当做一个方法来调用。
     *         (3)当一个方法被调用时,this被绑定到该对象。可以使用this去访问对象,所以它能从对象中取值或修改对象。
     *             this到对象的绑定发生在调用的时候。
     *     2>函数调用模式
     *         (1)当函数以此模式调用时,this被绑定到全局对象。这是语言设计上的一个错误。倘若语言设计正确,
     *             当内部函数被调用时,this应该仍然绑定到外部函数的this变量,
     *             这个设计错误的后果是方法不能利用内部函数来帮助它工作,因为内部函数的this被绑定了错误的值,
     *             所以不能共享该方法对对象的访问权。
     *         (2)解决方案:如果该方法定义一个变量(如that)并给它赋值为this,那么内部就可以通过那个变量访问到this。
     *     3>构造器调用模式
     *         (1)如果在一个函数前面带上new来调用,那么将创建一个隐藏连接到该函数的prototype成员的新对象,
     *             同时this将会被绑定到那个新对象上。
     *         (2)我们通常以大写格式来命名构造器函数。
     *     4>Apply、Call调用模式
     *         (1)apply(thisObj, argsArray)
     *             第一个是将被绑定给this的值,第二个是参数数组。
     *         (2)call(thisObj, arg1, arg2, ...)
     *             第一个是将被绑定给this的值,之后为参数列表枚举。
     *     
     *     我们需要深入区分前两者调用模式,深入理解汤姆大叔的博客便知其区别了——
     *     深入理解JavaScript系列(13):This? Yes,this!
     */
     1 //分析
     2 (function ($) {
     3     
     4     window.color = 'red';
     5     
     6     /**
     7      * 1>this与上下文中可执行代码的类型有直接关系,this值在进入上下文时确定,并且在上下文运行期间永久不变。
     8      * 2>this值的首要特点(或许是最主要的)是它不是静态的绑定到一个函数。
     9      * 3>this值的确定与引用类型的值相关,其通用规则如下:
    10      *     在一个函数上下文中,this由调用者提供,由调用函数的方式来决定。
    11      *     如果调用括号()的左边是引用类型的值,this将设为引用类型值的base对象(base object),
    12      *     在其他情况下(与引用类型不同的任何其它属性),这个值为null。
    13      */
    14     var myapp = {
    15         color: 'green',
    16         paint: function (node) {
    17             node.style.color = this.color;
    18         }
    19     };
    20     
    21     var findNodes = function (callback) {
    22         
    23         var nodes = $('div');
    24         for (var i = 0, len = nodes.length; i < len; i += 1) {
    25             //此时经过中间值计算后,callback的base是global,因此调用callback后的this指向global
    26             callback(nodes[i]);
    27         }
    28     }
    29     //findNodes的调用模式为函数调用模式
    30     findNodes(myapp.paint);
    31     
    32     //myapp.paint()的调用模式为方法调用模式
    33     myapp.paint($('div').get(0));
    34     
    35 })(jQuery);
    36 
    37 //改造
    38 (function ($) {
    39     
    40     var myapp = {
    41         color: 'green',
    42         paint: function (node) {
    43             node.style.color = this.color;
    44         }
    45     };
    46     
    47     var findNodes = function (callback_obj, callback) {
    48         var nodes = $('div');
    49         for (var i = 0, len = nodes.length; i < len; i += 1) {
    50             if (typeof callback === 'function') {
    51                 //改造的方式无非是改变回调函数的作用域
    52                 callback.call(callback_obj, nodes[i]);
    53             }
    54             if (typeof callback === 'string') {
    55                 callback_obj[callback](nodes[i]);
    56             }
    57         }
    58     };
    59     //我们指定在myapp对象的作用域下,执行myapp.paint函数
    60     //传递一个对象和一个方法
    61     findNodes(myapp, myapp.paint);
    62     //传递一个对象和方法名称字符串
    63     findNodes(myapp, 'paint');
    64     
    65 })(jQuery);
    /**
     * 本篇随笔参考资料:
     * 
     * 《JavaScript语言精粹》
     *     第4章:函数
     * 《JavaScript模式》
     *     第4章:函数
     * 《深入理解JavaScript系列——汤姆大叔的博客》
     *     深入理解JavaScript系列(13):This? Yes,this!
     */

      深入理解JavaScript系列的篇篇文章都是精华,集合了很多JavaScript书籍的核心思想,建议博友细细推敲。

      以下列举本人已经读过、加以深入理解并部分应用于实践的文章——

    深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点
    深入理解JavaScript系列(2):揭秘命名函数表达式
    深入理解JavaScript系列(3):全面解析Module模式
    深入理解JavaScript系列(4):立即调用的函数表达式
    深入理解JavaScript系列(5):强大的原型和原型链
    深入理解JavaScript系列(9):根本没有“JSON对象”这回事!
    深入理解JavaScript系列(10):JavaScript核心(晋级高手必读篇)
    深入理解JavaScript系列(11):执行上下文(Execution Contexts)
    深入理解JavaScript系列(12):变量对象(Variable Object)
    深入理解JavaScript系列(13):This? Yes, this!
    深入理解JavaScript系列(14):作用域链(Scope Chain)
    深入理解JavaScript系列(15):函数(Functions)
    深入理解JavaScript系列(16):闭包(Closures)

      很惭愧,看的并不是很多,还有不少东西要学,我一直信奉一个学习理念——

      抓住一个点,深究下去;
      抓住一个点,扩展下去!

      还有很多可以研究的知识,还有很多可以整合的知识。加油吧,给自己打打气!

  • 相关阅读:
    saltstack远程执行
    centos7防火墙的关闭和禁用
    saltstack 安装使用
    flask基础-第一个flask-jinja2-response三剑客-request-session
    linux服务器排查病毒纪实
    读完这篇文章,就基本搞定了Redis主从复制
    Django学习【第26篇】:中介模型以及优化查询以及CBV模式
    Django学习【第26篇】:后端CORS解决跨域问题
    Django学习【第25篇】:前端Jsonp解决跨域问题
    Django学习【第24篇】:JS实现的ajax和同源策略
  • 原文地址:https://www.cnblogs.com/jinguangguo/p/2712475.html
Copyright © 2011-2022 走看看