• 【读书笔记】读《JavaScript模式》


      API模式:回调模式、配置对象、返回函数;

      初始化模式:即时函数、即时对象初始化、初始化分支;

      性能模式:备忘模式、自定义模式

     1 //*********************** API模式 ***********************
     2 /**
     3  * ---------------------- 回调模式 ----------------------
     4  * 
     5  * 1>要写出通用和可复用的代码,回调模式可以帮助实现这种通用化。
     6  * 2>不需要预测和实现能想到的每一项功能,因为这样会迅速使我们的代码膨胀,
     7  *     而绝大多数用户永远不会需要其中大量的功能。相反,可以专注于核心功能并提供“挂钩”形式的回调函数,
     8  *     这会使我们很容易构建、扩展,以及自定义我们的方法。
     9  */
    10 //方式一
    11 var findNodes = function () {
    12     var i = 10000,
    13         nodes = [],
    14         found;
    15     while (i) {
    16         i -= 1;
    17         //这里是复杂的业务逻辑
    18         nodes.push(found);
    19     }
    20     return nodes;
    21 }
    22 
    23 var hide = function (nodes) {
    24     for (var i = 0, len = nodes.length; i < len; i += 1) {
    25         nodes[i].style.display = 'none';
    26     }
    27 }
    28 
    29 hide(findNodes());
    30 
    31 //方式二
    32 var findNodes = function (callback) {
    33     var i = 10000,
    34         nodes = [],
    35         found;
    36     while (i) {
    37         i -= 1;
    38         //这里是复杂的业务逻辑
    39         if (typeof callback === 'function') {
    40             callback(found);
    41         }
    42         nodes.push(found);
    43     }
    44     return nodes;
    45 }
    46 
    47 var hide = function (node) {
    48     node.style.display = 'none';
    49 }
    50 
    51 findNodes(hide);
    52 
    53 //简洁点,将回调函数直接写在findNodes函数中
    54 findNodes(function (node) {
    55     node.style.display = 'block';
    56 })
    57 
    58 /**
    59  * ---------------------- 配置对象模式 ----------------------
    60  * 
    61  * 封装传递参数为一个对象,灵活了函数的调用方式,何乐而不为
    62  */
    63 function addPerson(name, gender, age, address) {
    64     //...
    65 }
    66 
    67 //将参数封装
    68 var conf = {
    69     name: 'king',
    70     gender: 'male',
    71     age: 25,
    72     address: 'xxxxxx'
    73 }
    74 addPerson(conf);
    75 
    76 //简写之
    77 addPerson({
    78     name: 'king',
    79     gender: 'male',
    80     age: 25,
    81     address: 'xxxxxx'
    82 })
    83 
    84 /**
    85  * ---------------------- 返回函数模式 ----------------------
    86  * 
    87  * 函数里面返回函数,它创建了一个闭包,可以使用这个闭包存储一些私有数据,
    88  * 而这些数据仅可被该返回函数访问,但外部代码却无法访问。
    89  */
    90 var setup = function () {
    91     var count = 0;
    92     return function () {
    93         return count++;
    94     }
    95 }
    96 var next = setup();
    97 next();    //1
    98 next();    //2
    99 next();    //3
    //*********************** 初始化模式 ***********************
    /**
     * ---------------------- 即时函数模式 ----------------------
     */
    //文件module1.js中定义的模块module1
    (function () {
        //模块1的所有代码
    })();
    
    //文件module2.js中定义的模块module2
    (function () {
        //模块2的所有代码
    })();
    
    /**
     * ---------------------- 即时对象初始化模式 ----------------------
     * 
     * 这种模式的优点与即时函数模式的优点是相同的:可以在执行一次性的初始化任务时保护全局命名空间。、
     * 与仅仅将一堆代码包装到匿名函数的方法相比。这种模式看起来设计更多的语法特征,
     * 但是如果初始化任何更加复杂(它们也往往的确比较复杂),它会使整个初始化过程显得更有结构化。
     * 其语法结构如下:
     * ({...}).init();
     * ({...}.init());
     */
    ({
        name: 'king',
        password: '123',
        say: function () {
            return 'I am ' + this.name + ', and my password is ' + this.password;
        },
        init: function () {
            console.log(this.say());
        }
        /**
         * 这种模式主要适用于一次性的任务,而且在init()完毕后也没有保存对该对象的访问。
         * 如果想在init()完毕后保存对该对象的一个引用,可以通过在init()尾部添加"return this;"语句实现该功能。
         */
    }).init();    //I am king, and my password is 123
    
    /**
     * ---------------------- 初始化时分支模式 ----------------------
     */
    //每次调用utils.addListener()或utils.removeListener()时,都会重复地进行相同检查
    var utils = {
        addListener: function (elem, type, fn) {
            if (typeof window.addEventListener === 'function') {
                elem.addEventListener(type, fn, false);
            } else if (typeof window.attachEvent === 'function') {    //IE
                elem.attachEvent('on' + type, fn);
            } else {
                elem['on' + type] = fn;
            }
        },
        removeListener: function () {
            if (typeof window.removeEventListener === 'function') {
                elem.removeEventListener(type, fn, false);
            } else if (typeof window.detachEvent === 'function') {    //IE
                elem.detachEvent('on' + type, fn);
            } else {
                elem['on' + type] = null;
            }
        }
    }
    
    //采用分支
    var utils = {
        addListener: null,
        removeListener: null
    }
    //分开嗅探浏览器特征,然后使用加载时分支仅执行一次嗅探
    if (typeof window.addEventListener === 'function') {
        utils.addListener = function (elem, type, fn) {
            elem.addEventListener(type, fn, false);
        };
        utils.removeListener = function (elem, type, fn) {
            elem.removeListener(type, fn, false);
        };
    } else if (typeof window.detachEvent === 'function') {    //IE
        utils.addListener = function (elem, type, fn) {
            elem.attachEvent('on' + type, fn);
        };
        utils.removeListener = function (elem, type, fn) {
            elem.detachEvent('on' + type, fn);
        };
    } else {
        utils.addListener = function (elem, type, fn) {
            elem['on' + type] = fn;
        };
        utils.removeListener = function (elem, type, fn) {
            elem['on' + type] = null;
        };
    }
    //*********************** 性能模式 ***********************
    /**
     * ---------------------- 备忘模式 ----------------------
     * 
     * 使用函数属性以便使得计算过的值无须再次计算
     */
    var myfunc = function (param) {
        if (!myfunc.cache[param]) {
            var result = {};
            //...开销很大的操作...
            myfunc.cache[param] = result;
        }
        return myfunc.cache[param];
    }
    //缓存存储
    myfunc.cache = {};
    
    
    /**
     * ---------------------- 自定义函数模式 ----------------------
     * 
     * 当函数有一些初始化准备工作要做,并且仅需要执行一次,那么这个模式就非常有用。
     * 因为并没有任何理由去执行本可以避免的重复工作,即该函数的一些部门可能并不再需要。
     * 在这种情况下,自定义函数可以更新自身的实现。使用此模式可以显著地帮助提升应用程序的性能,
     * 这是由于重新定义的函数仅执行了更少的工作。
     */
    var scareMe = function () {
        alert('Boo!');
        scareMe = function () {
            alert('Double boo!');
        };
    }
    
    scareMe();    //Boo!
    scareMe();    //Double boo!
    scareMe();    //Double boo!
  • 相关阅读:
    Linux 进程管理
    强大的bat文件搞定系统所有问题
    Java多线程设计要点
    Linux 内核
    Linux 文件和目录管理之列出、删除、复制、移动及改名
    命令dd 及简单应用
    Transferring Files with SFTP or SCP
    简述Linux文件搜索
    加强Eclipse代码自动提示的方法
    Cisco交换机配置新手篇之端口配置
  • 原文地址:https://www.cnblogs.com/jinguangguo/p/3477612.html
Copyright © 2020-2023  润新知