• Javascript编程模式(JavaScript Programming Patterns)Part 2.(高级篇)


    1. 模块编程模式的启示(Revealing Module Pattern)
    2. 客户端对象(Custom Objects)
    3. 懒函数定义(Lazy Function Definition)

    Christian 不喜欢module pattern,并对此编程模式进行了研究.在此基础上想出了一些新的东西他称之为 Revealing Module Pattern. 正如其名, 这种模式来源于Module Pattern, 但相比之下结构感更强且利于理解,尤其是在开发团队中将自己的代码移交给别人更容易上手.

    首先,他还是一种基础的function定义与回调:

    var anchorChange4 = function () {}();

    其次,定义属性与方法时我们不用花太多的时间去在意 他们是否是 private 或者 public:

     // this will be a private property
        var config = {
            colors: [ "#F63", "#CC0", "#CFF" ]
        }
        // this will be a public method
        var init = function () {
            var self = this;
        }
        // assign reference to current object to "self"
        // get all links on the page
        var anchors = document.getElementsByTagName("a");
        var size = anchors.length;
        for (var i = 0; i < size; i++) {
            anchors[i].color = config.colors[i];
            anchors[i].onclick = function () {
                self.changeColor(this, this.color);
                // this is bound to the anchor object
                return false;
            };
        }
        // this will be a public method
        var changeColor = function (linkObj, newColor) {
            linkObj.style.backgroundColor = newColor;
        }

    现在我们说一下核心部分.切换到 Module Pattern模式下, 你已经注意到了在结束时return 语句中包含public 属性和方法. 在 Revealing Module Pattern模式下, 你只需要放入共享的属性与方法即可:

     return {
         // declare which properties and methods are supposed to be public
         init: init,
        changeColor: changeColor
        } 

    只有2个公共属性需要初始化一个是 init (负责编译前的准备工作) 和 changeColor (负责函数调用时的 clicked事件). 这样代码保持了整洁:

      // revealing module pattern
        var anchorChange4 = function () {
            // this will be a private property
            var config = { colors: [ "#F63", "#CC0", "#CFF" ] }
            // this will be a public method
            var init = function () {
                var self = this;
            }
            // assign reference to current object to "self"
            // get all links on the page
            var anchors = document.getElementsByTagName("a");
            var size = anchors.length;
            for (var i = 0; i < size; i++) {
                anchors[i].color = config.colors[i];
                anchors[i].onclick = function () {
                    self.changeColor(this, this.color);
                    // this is bound to the anchor object
                    return false;
                };
            }
    
    
            // this will be a public method
            var changeColor = function (linkObj, newColor) {
                linkObj.style.backgroundColor = newColor;
            }
    
            return {
                // declare which properties and methods are supposed to be public
                init: init,
                changeColor: changeColor
            }
        } ();

    与所有的编程模式一样, 你需要在script代码快中调用:

     <script type="text/javascript"> 
                anchorChange4.init(); 
     </script>

    客户端对象(Custom Objects)

    创建一类对象在面向对象的语言中很常见. 但是Javascript与面向对象相比较是基于对象的语言. 在JavaScript中, 在接受参数创建对象时你必须调用  function 构造器 .你不能像java 一样有类与子类( Java ).

    首先, 我们需要为我们的对象创建函数构造器:

    var anchorChanger = function () {};

    我们初始化了一个空的函数构造器,稍后为对象添加 init 方法.

    使用原型, 对我们的对象可以添加各种属性且可以访问. 最后设置了 3 属性, 也就是: config, changeColor and init.

        anchorChanger.prototype.config = {
            colors: [ "#F63", "#CC0", "#CFF" ]
        }
    
        anchorChanger.prototype.changeColor =
                function (linkObj, newColor) {
                    linkObj.style.backgroundColor = newColor;
                };
        
        anchorChanger.prototype.init = function () {
            var self = this;
            var anchors = document.getElementsByTagName("a");
            var size = anchors.length;
            for (var i = 0; i < size; i++) {
                anchors[i].color = self.config.colors[i];
                anchors[i].onclick = function () {
                    self.changeColor(this, this.color);
                    return false;
                };
            }
        };

     Mike West指出, 使用原型的效率会很高.他不必每次都创建对象访问对象.

        // custom object constructor
        var anchorChanger = function () {
            this.init();
        };
        anchorChanger.prototype.config = {
            colors: [ "#F63", "#CC0", "#CFF" ]
        }
        anchorChanger.prototype.changeColor = function (linkObj, newColor) {
            linkObj.style.backgroundColor = newColor;
        };
        anchorChanger.prototype.init = function () {
            var self = this;
        } 
        // get all links on the page
        var anchors = document.getElementsByTagName("a");
        var size = anchors.length;
        for (var i = 0; i < size; i++) {
            anchors[i].color = self.config.colors[i];
            anchors[i].onclick = function () {
                self.changeColor(this, this.color);
                return false;
            };
        } ;

    在页面中我们只需要声明一个 anchorChanger的接口即可:

    <script type="text/javascript"> 
    new anchorChanger(); 
    </script>

    惰性函数定义(Lazy Function Definition)

    Peter Michaux 提出了 Lazy Function Definition 模式. 当你在页面中反复计算、调用函数多次时这种模式很实用.在这种模式下你要确定你的方法只做了一次,且仅仅做了一次.例子中 Peter 给出了在不同浏览器宿主环境不同而处理滚动的功能也不同.在不同浏览器模型中, 当函数在第一时间被调用时,滚动功能也不同(此处参看lazy-function-definition-pattern).

    对于我们的任务而言,这种模式没有提供任何的优势,因为在这里我们没有繁重复杂的计算. 我们仅仅是展示一下这种模式是如何工作的:

    var anchorChange5 = function () {};

    像别的模式一样添加一些功能,代码如下:

      // define configuration
        var config = {
            colors: [ "#F63", "#CC0", "#CFF" ]
        };
        // get all links
        var anchors = document.getElementsByTagName("a");
        var size = anchors.length;
        // loop through anchors and attach events 
        for (var i = 0; i < size; i++) {
            anchors[i].color = config.colors[i];
            anchors[i].onclick = function ()
            { anchorChange5().changeColor(this, this.color); 
                return false;
            };
        } 

    以上代码确保在调用时运行一次,所以不需要包含随后调用函数的性质.在 Lazy Function Definition 模式,需要从新定义函数声明:

      // redefine function so that it only holds the changeColor function 
        anchorChange5 = function () {
            return {
                changeColor: function (linkObj, newColor) {
                    linkObj.style.backgroundColor = newColor;
                }
            };
        };

    所以懒函数定义模式代码如下:

     // lazy function definition
        var anchorChange5 = function () {
            // define configuration 
            var config = { colors: [ "#F63", "#CC0", "#CFF" ] };
            // get all links
            var anchors = document.getElementsByTagName("a");
            var size = anchors.length;
            // loop through anchors and attach events
            for (var i = 0; i < size; i++) {
                anchors[i].color = config.colors[i];
                anchors[i].onclick = function () {
                    anchorChange5().changeColor(this, this.color);
                    return false;
                };
            }
            // redefine function so that it only holds the changeColor function
            anchorChange5 = function () {
                return { changeColor: function (linkObj, newColor) {
                    linkObj.style.backgroundColor = newColor;
                } };
            };
        };

    发生了什么:

    1. anchorChange5 在页面上调用和定义 config 变量与 anchors集合
    2. 每一个 anchor会被粘贴上一个onclick事件, 当被触发调用 changeColor方法并且从新声明 anchorChange5 function
    3. 在此之后, anchorChange5会从新声明并可以访问到只持有 changeColor 方法

    在body之间,要调用 anchorChange5 :

    <script type="text/javascript">    
                anchorChange5();
    </script>
  • 相关阅读:
    docker常用命令
    Jenkins 插件开发记录
    【转】python作用域
    git备忘录
    【笔记】script.sh: source: not found in docker 问题
    (转)JavaScript判断浏览器类型及版本
    (转)webstorm快捷键
    (转)javaScript call 函数的用法说明
    (转载)记录函数 getStyle() 获取元素 CSS 样式
    (转)resize扩展
  • 原文地址:https://www.cnblogs.com/YcYYcY/p/3794005.html
Copyright © 2020-2023  润新知