咱們如今須要寫一個 foo 函數,這個函數返回首次調用時的 Date 對象,注意是首次。瀏覽器
var t;
function foo() { if (t) return t; t = new Date() return t; }
問題有兩個,一是污染了全局變量,二是每次調用 foo 的時候都須要進行一次判斷。閉包
咱們很容易想到用閉包避免污染全局變量。函數
var foo = (function() { var t; return function() { if (t) return t; t = new Date(); return t; } })();
然而仍是沒有解決調用時都必須進行一次判斷的問題。spa
函數也是一種對象,利用這個特性,咱們也能夠解決這個問題。對象
function foo() { if (foo.t) return foo.t; foo.t = new Date(); return foo.t; }
依舊沒有解決調用時都必須進行一次判斷的問題。事件
不錯,惰性函數就是解決每次都要進行判斷的這個問題,解決原理很簡單,重寫函數。io
var foo = function() { var t = new Date(); foo = function() { return t; }; return foo(); };
DOM 事件添加中,爲了兼容現代瀏覽器和 IE 瀏覽器,咱們須要對瀏覽器環境進行一次判斷:function
// 簡化寫法 function addEvent (type, el, fn) { if (window.addEventListener) { el.addEventListener(type, fn, false); } else if(window.attachEvent){ el.attachEvent('on' + type, fn); } }
問題在於咱們每當使用一次 addEvent 時都會進行一次判斷。class
利用惰性函數,咱們能夠這樣作:變量
function addEvent (type, el, fn) { if (window.addEventListener) { addEvent = function (type, el, fn) { el.addEventListener(type, fn, false); } } else if(window.attachEvent){ addEvent = function (type, el, fn) { el.attachEvent('on' + type, fn); } } }
固然咱們也能夠使用閉包的形式:
var addEvent = (function(){ if (window.addEventListener) { return function (type, el, fn) { el.addEventListener(type, fn, false); } } else if(window.attachEvent){ return function (type, el, fn) { el.attachEvent('on' + type, fn); } } })();
當咱們每次都須要進行條件判斷,其實只須要判斷一次,接下來的使用方式都不會發生改變的時候,想一想是否能夠考慮使用惰性函數。