深入理解JavaScript系列(47):对象创建模式(上篇)


Posted in Javascript onMarch 04, 2015

介绍

本篇主要是介绍创建对象方面的模式,利用各种技巧可以极大地避免了错误或者可以编写出非常精简的代码。

模式1:命名空间(namespace)

命名空间可以减少全局命名所需的数量,避免命名冲突或过度。一般我们在进行对象层级定义的时候,经常是这样的:

var app = app || {};

app.moduleA = app.moduleA || {};

app.moduleA.subModule = app.moduleA.subModule || {};

app.moduleA.subModule.MethodA = function () {

    console.log("print A");

};

app.moduleA.subModule.MethodB = function () {

    console.log("print B");

};

如果层级很多的话,那就要一直这样继续下去,很是混乱。namespace模式就是为了解决这个问题而存在的,我们看代码:
// 不安全,可能会覆盖已有的MYAPP对象

var MYAPP = {};

// 还好

if (typeof MYAPP === "undefined") {

    var MYAPP = {};

}

// 更简洁的方式

var MYAPP = MYAPP || {};
//定义通用方法

MYAPP.namespace = function (ns_string) {

    var parts = ns_string.split('.'),

        parent = MYAPP,

        i;
    // 默认如果第一个节点是MYAPP的话,就忽略掉,比如MYAPP.ModuleA

    if (parts[0] === "MYAPP") {

        parts = parts.slice(1);

    }
    for (i = 0; i < parts.length; i += 1) {

        // 如果属性不存在,就创建

        if (typeof parent[parts[i]] === "undefined") {

            parent[parts[i]] = {};

        }

        parent = parent[parts[i]];

    }

    return parent;

};

调用代码,非常简单:
// 通过namespace以后,可以将返回值赋给一个局部变量

var module2 = MYAPP.namespace('MYAPP.modules.module2');

console.log(module2 === MYAPP.modules.module2); // true
// 跳过MYAPP

MYAPP.namespace('modules.module51');
// 非常长的名字

MYAPP.namespace('once.upon.a.time.there.was.this.long.nested.property');

模式2:定义依赖

有时候你的一个模块或者函数可能要引用第三方的一些模块或者工具,这时候最好将这些依赖模块在刚开始的时候就定义好,以便以后可以很方便地替换掉。

var myFunction = function () {

    // 依赖模块

    var event = YAHOO.util.Event,

        dom = YAHOO.util.dom;
    // 其它函数后面的代码里使用局部变量event和dom

};

模式3:私有属性和私有方法

JavaScript本书不提供特定的语法来支持私有属性和私有方法,但是我们可以通过闭包来实现,代码如下:

function Gadget() {

    // 私有对象

    var name = 'iPod';

    // 公有函数

    this.getName = function () {

        return name;

    };

}

var toy = new Gadget();
// name未定义,是私有的

console.log(toy.name); // undefined
// 公有方法访问name

console.log(toy.getName()); // "iPod"
var myobj; // 通过自执行函数给myobj赋值

(function () {

    // 自由对象

    var name = "my, oh my";
    // 实现了公有部分,所以没有var

    myobj = {

        // 授权方法

        getName: function () {

            return name;

        }

    };

} ());

模式4:Revelation模式

也是关于隐藏私有方法的模式,和《深入理解JavaScript系列(3):全面解析Module模式》里的Module模式有点类似,但是不是return的方式,而是在外部先声明一个变量,然后在内部给变量赋值公有方法。代码如下:

var myarray;
(function () {

    var astr = "[object Array]",

        toString = Object.prototype.toString;
    function isArray(a) {

        return toString.call(a) === astr;

    }
    function indexOf(haystack, needle) {

        var i = 0,

            max = haystack.length;

        for (; i < max; i += 1) {

            if (haystack[i] === needle) {

                return i;

            }

        }

        return -1;

    }
    //通过赋值的方式,将上面所有的细节都隐藏了

    myarray = {

        isArray: isArray,

        indexOf: indexOf,

        inArray: indexOf

    };

} ());
//测试代码

console.log(myarray.isArray([1, 2])); // true

console.log(myarray.isArray({ 0: 1 })); // false

console.log(myarray.indexOf(["a", "b", "z"], "z")); // 2

console.log(myarray.inArray(["a", "b", "z"], "z")); // 2
myarray.indexOf = null;

console.log(myarray.inArray(["a", "b", "z"], "z")); // 2

模式5:链模式

链模式可以你连续可以调用一个对象的方法,比如obj.add(1).remove(2).delete(4).add(2)这样的形式,其实现思路非常简单,就是将this原样返回。代码如下:

var obj = {

    value: 1,

    increment: function () {

        this.value += 1;

        return this;

    },

    add: function (v) {

        this.value += v;

        return this;

    },

    shout: function () {

        console.log(this.value);

    }

};
// 链方法调用

obj.increment().add(3).shout(); // 5
// 也可以单独一个一个调用

obj.increment();

obj.add(3);

obj.shout();

总结

本篇是对象创建模式的上篇,敬请期待明天的下篇。

Javascript 相关文章推荐
jquery实现省市select下拉框的替换(示例代码)
Feb 22 Javascript
javascript(js)的小数点乘法除法问题详解
Mar 07 Javascript
jQuery实现的左右移动焦点图效果
Jan 14 Javascript
AngularJS $injector 依赖注入详解
Sep 14 Javascript
jQuery实现立体式数字滚动条增加效果
Dec 21 Javascript
Vue.Js中的$watch()方法总结
Mar 23 Javascript
前端构建工具之gulp的配置与搭建详解
Jun 12 Javascript
深入理解angular2启动项目步骤
Jul 15 Javascript
weui框架实现上传、预览和删除图片功能代码
Aug 24 Javascript
谈谈为什么你的 JavaScript 代码如此冗长
Jan 30 Javascript
javascript实现小型区块链功能
Apr 03 Javascript
详解小程序用户登录状态检查与更新实例
May 15 Javascript
深入理解JavaScript系列(46):代码复用模式(推荐篇)详解
Mar 04 #Javascript
深入理解JavaScript系列(45):代码复用模式(避免篇)详解
Mar 04 #Javascript
深入理解JavaScript系列(44):设计模式之桥接模式详解
Mar 04 #Javascript
JS实现FLASH幻灯片图片切换效果的方法
Mar 04 #Javascript
javascript下拉框选项单击事件的例子分享
Mar 04 #Javascript
js实现仿QQ秀换装效果的方法
Mar 04 #Javascript
深入理解JavaScript系列(43):设计模式之状态模式详解
Mar 04 #Javascript
You might like
file_get_contents获取不到网页内容的解决方法
2013/03/07 PHP
sql注入与转义的php函数代码
2013/06/17 PHP
thinkphp微信开发(消息加密解密)
2015/12/02 PHP
PHP MYSQL实现登陆和模糊查询两大功能
2016/02/05 PHP
thinkphp5 URL和路由的功能详解与实例
2017/12/26 PHP
Yii2.0框架behaviors方法使用实例分析
2019/09/30 PHP
通过action传过来的值在option获取进行验证的方法
2013/11/14 Javascript
JS中使用变量保存arguments对象的方法
2016/06/03 Javascript
JS事件添加和移出的兼容写法示例
2016/06/20 Javascript
js两种拼接字符串的简单方法(必看)
2016/09/02 Javascript
jQuery列表检索功能实现代码
2017/07/17 jQuery
浅谈angularJS的$watch失效问题的解决方案
2017/08/11 Javascript
Angular4 ElementRef的应用
2018/02/26 Javascript
es6基础学习之解构赋值
2018/12/10 Javascript
ES6实现图片切换特效代码
2020/01/14 Javascript
jQuery中getJSON跨域原理的深入讲解
2020/09/02 jQuery
[07:57]2018DOTA2国际邀请赛寻真——PSG.LGD凤凰浴火
2018/08/12 DOTA
python简单线程和协程学习心得(分享)
2017/06/14 Python
Python格式化日期时间操作示例
2018/06/28 Python
Python绘制KS曲线的实现方法
2018/08/13 Python
Python openpyxl 遍历所有sheet 查找特定字符串的方法
2018/12/10 Python
python实现杨氏矩阵查找
2019/03/02 Python
python 使用opencv 把视频分割成图片示例
2019/12/12 Python
HTML5+JS实现俄罗斯方块原理及具体步骤
2013/11/29 HTML / CSS
HTML 5 input placeholder 属性如何完美兼任ie
2014/05/12 HTML / CSS
利用HTML5 Canvas制作键盘及鼠标动画的实例分享
2016/03/15 HTML / CSS
html5调用app分享功能示例(WebViewJavascriptBridge)
2018/03/21 HTML / CSS
关于廉洁的广播稿
2014/01/30 职场文书
留学顾问岗位职责
2014/04/14 职场文书
2015年八一建军节慰问信
2015/03/23 职场文书
幼儿园六一主持词开场白
2015/05/28 职场文书
2019单位介绍信怎么写
2019/06/24 职场文书
美甲店的创业计划书模板
2019/08/23 职场文书
淡雅古典唯美少女娇媚宁静迷人写真
2022/03/21 杂记
MySQL详解进行JDBC编程与增删改查方法
2022/06/16 MySQL
Python中的socket网络模块介绍
2022/07/23 Python