初识Javascript单体模式

单体模式,这一词语,第一次听说是源于与老鱼(事后第二天才得知电话的另一方是老鱼)先生的电话交流,当时他问我“什么是单体模式?”,天呐,我可是第一次听说这个词,只好条件反射式的回答“I don’t know!”,后来他给我分享了js一些设计思想,很受启发,最后向我推荐了《Javascript设计模式》,显然,这本书已经列入了的我的图书阅读有序列表当中。

由于手边没有《Javascript设计模式》这本书,只是在网上搜索了单体模式的定义,大脑中还是很模糊,第二天,我终于忍不住请教了涂料先生,因为我知道他一定知道。

他很平易近人,很开源性的介绍此模式或称为思想,还推荐了文章 《小议javascript设计模式》,正是由于这篇文章我知道了老鱼。

至于什么是单体模式,什么是惰性单体模式,在此就不做介绍,非常OO的思想,因为在文章《小议javascript设计模式》中介绍的很明白,看文章即可,老鱼的文章很长,我花了一上午的时间才看完。

下面我想着重谈一下 Javascript 中的 null undefined,借鉴老鱼的惰性单体模式例子:

var ioldfish = (function(){
  var uniqueInstance;
  var name = '老鱼';
  var age = 27;
  function constructor(){
    return{
      getName:function(){
        alert(name); 
      },
      getAge:function(){
        alert(age); 
      }
    }
  } 
  return{
    isInstance:function(){
      if(uniqueInstance == null){
        uniqueInstance = constructor();
      }
      return uniqueInstance;
    }
  } 
})();
ioldfish.isInstance().getName();

其中有一行 if(uniqueInstance == null) ,看了又看,很是匪夷所思,为什么不写成 if(uniqueInstance == undefined) ,个人认为 if(uniqueInstance == undefined) 会略好,原因如下:

要执行javascript代码,必须要先经过javascript引擎编译,个人觉得编译过程应该会类似于java虚拟机编译过程,会预先将var开头的变量定义为window.undefined,所以在执行函数实例 ioldfish 前,就已经得到:

uniqueInstance === window.undefined

在执行函数实例时,内部代码会逐行运行,当运行到

var uniqueInstance;

这句时,由于并没有改变 uniqueInstance 的值,此时 uniqueInstance 的值还会是 window.undefined ,所以在接下来的判断语句,

if(uniqueInstance == null){
  uniqueInstance = constructor();
}

应该改为

if(uniqueInstance == undefined){
  uniqueInstance = constructor();
}

看到这儿您或许会说 window.undefined==null 嘛,所以

if(uniqueInstance == null)

这样写完全ok的,是的,但这个 if 语句是做了两次判断,即:

if(uniqueInstance == window.undefined == null) 

能一次判断的事情,为什么要判断两次呢?

先看节选的代码:

function constructor(){
  return{
    getName:function(){
      alert(name); 
    },
    getAge:function(){
      alert(age); 
    }
  }
}
uniqueInstance = constructor();

这段代码说明 uniqueInstance 是对 constructor 函数实例 return 出来对象的引用。所以进行
iuniqueInstance == null 判断而不用 uniqueInstance == undefined,是为了 统一 uniqueInstance 的引用类型,从而更方便肉眼读懂代码进行判断。

但是问题又来了

alert(typeof null); //output 'object'

这证明了 null 是一个对象实例,但请看下面的代码:

alert(null instanceof Object); //output 'false'
alert(null.constructor); //浏览器 typeError 错误

这两段代码说明 null 不是 Object 的实例,顶多算是对象的占位符吧,所以 iuniqueInstance == null 真的比 uniqueInstance == undefined 更优么?有待思考…

如果真的想用 iuniqueInstance == null 判断是否已经指向具体对象,为什么不直接将 var uniqueInstance = null; 呢?例如下面的更改

var ioldfish = (function(){
  var uniqueInstance = null; //原先是var uniqueInstance;
  var name = '老鱼';
  var age = 27;
  ...
  ...
})();
ioldfish.isInstance().getName();

写成 var oUniqueInstance == null ,或许又会更好…

呵呵,至此纠结告一段落,对于这样一大段有的没的的话语值不值得去花时间思考,还有待高人指点迷津…

如果老鱼先生也读到过此文话,希望可以将《小议javascript设计模式》文章中

该模式的应用场景还是很多的,是不是遇见过页面中需要加载很大的一个日历控件,但并非所有用户都用的到呢?

这句话举一个例子,这会使一批像我这样经验不足的人更好的理解您这句话的意思的,谢谢!

最后,对于新手能有机会和专家交流,了解js设计思想,不闭门造车,大路向前,少走弯路,人生足矣!还是挤时间去看《javascript设计模式》吧!

This entry was posted in Javascript/Ajax and tagged , , , , . Bookmark the permalink. Both comments and trackbacks are currently closed.