浅析 JavaScript 组件编写

之前因项目需要也编写过一些简单的JS组件,大多是基于JQuery库的,一直也没有过总结,导致再次写到的时候还去Google, 近日看到一个文章总结的挺好,拿过整理一下做个备忘。

 

此次同样是基于jquery库来开发,根据一个例子来循序渐进地说明。

了解AngularJs的同学知道,其最具魅力的特点莫过于双向绑定,那么我们今天也来实现一个双向绑定的组件,在一个text文本框后面显示输入的文本内容。

 <大概长这个模样>

 

1. 常规实现思路   

 1 <input id="txt-con" type="text" />
 2 <script>
 3     $(function(){
 4         var textInput = $("#txt-con");
 5         textInput.bind('keyup', function(){
 6             if (textInput.val()) {
 7                 appendText(this, textInput.val());    
 8             }
 9         });
10 
11         var appendText = function(target, content) {
12             var id = target.id + "-present";
13             if ($("#" + id).length > 0) {
14                 $("#" + id).text(content);
15             } else {
16                 $(target).after("<h2 id='"+id+"'>"+content+"</h2>");
17             }
18         }
19     })         
20 </script>

 

 以上代码可以妥妥的跑,达到预期的目的。但是细心的你会发现,我们的完全没有考虑作用域的问题,appendText 方法被暴露在全局作用域里面,如果这一个页面中有几十上百个这样的全局变量,那维护起来会疯掉。

 

2. “隔离”作用域

我们现在对上面的代码进行一些修改,引入一个单独的命名空间。

 1 var TextPresenter = {
 2     init: function(id){
 3         var textInput = $(id);
 4         var self = this;
 5         textInput.bind("keyup", function() {
 6             if(textInput.val()) {
 7                 self.appendText(this, textInput.val());    //注意这里的self变量,是将TextPresenter对象的引用赋给了self
 8             }
 9         })
10     },
11 
12     appendText: function(target, content){
13         var id = target.id + "-present";
14         if ($("#" + id).length > 0) {
15             $("#" + id).text(content);
16         } else {
17             $(target).after("<h2 id='"+id+"'>"+content+"</h2>");
18         }
19     },
20 } //以上部分你可以写进一个单独的js文件了,如jquery.textpresenter.js, 别忘了在document ready后初始化

  $(function(){
    TextPresenter.init("#txt-con");

  })

 

以上部分有点组件的雏形了不是,很多时候就这样被拿来用了,如果你再细细一想,好像有哪里不对,因为 TextPresenter 里面的所有成员变量都可以在外部被访问,而没有一点私有化的概念在里面。所以,说是隔离其实并没有真正隔离,只是看起来像是隔离了。

3. 真正隔离作用域

说到作用域的隔离,我们不得不引入闭包的概念了。曾经看了多少遍闭包的概念,然而实际用到的机会少之又少。借此也来实践一下闭包的基础知识。

 1 var TextPresenter = (function(){
 2     var appendText = function(target, content) { //此方法成了私有化方法,外部不可直接访问
 3         var id = target.id + "-present";
 4         if ($("#" + id).length > 0) {
 5             $("#" + id).text(content);
 6         } else {
 7             $(target).after("<h2 id='"+id+"'>"+content+"</h2>");
 8         } 
 9     };
10 
11     var TextPresenterFun = function() {
12         this.init = function(id) {
13             var textInput = $(id);
14             textInput.bind("keyup", function() {
15                 if(textInput.val()) {
16                     appendText(this, textInput.val());    
17                 }
18             })
19         }
20     };
21 
22     return TextPresenterFun; //返回构造函数,在调用此组件时需要实例化,然后调用init方法
23 
24 })();


  new TextPresenter().init("#txt-con"); //调用的过程

 

这种方式可以创建必要的私有方法,对外开放的只有init方法,具体的内部逻辑并不对外开放,满足我所要求的隔离作用域的需求。事实上,大多数的jQuery组件都是这么实现的。

 

先写这么多吧,都是些基础,作为一个入门,要走的路还长着啊。

 

posted on 2016-03-17 11:35  马铃豆  阅读(303)  评论(0编辑  收藏  举报

导航