首页 > 网站 > WEB开发 > 正文

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

2024-04-27 14:22:21
字体:
来源:转载
供稿:网友

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,changeColorandinit.

    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方法并且从新声明anchorChange5function
  3. 在此之后,anchorChange5会从新声明并可以访问到只持有changeColor 方法

在body之间,要调用anchorChange5:

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


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表