Effective JavaScript Item 55 接受配置对象作为函数參数
接受配置对象作为函数參数
尽管保持函数接受的參数的顺序非常重要,可是当函数可以接受的參数达到一定数量时。也会让用户非常头疼:
var alert = new Alert(100, 75, 300, 200,
"Error", message,
"blue", "white", "black",
"error", true);
随着函数的不断重构和进化。它可以接受的參数或许会越来越多。终于就像上面的样例那样。
对于这样的情况。JavaScript能够使用一个配置对象来替代以上的全部參数:
var alert = new Alert({
x: 100, y: 75,
width: 300, height: 200,
title: "Error", message: message,
titleColor: "blue", bgColor: "white", textColor: "black",
icon: "error", modal: true
});
这样做尽管会让代码略微冗长一些,可是毫无疑问它的优点是非常明显的:配置对象中的每一个属性的名字就好比是一份文档,来告诉用户这个属性是干什么用的。特别是对于布尔值。单独的传入true和false是非常难推断它的真实意图的。
使用这样的方式的另外一个优点是,全部的属性都是可选的。
假设配置对象中没有出现某个属性。那么就是用默认值来取代它。
var alert = new Alert(); // use all default parameter values
假设函数须要接受必须的參数,那么不妨将它放在配置对象的外面,就像以下这样:
var alert = new Alert(app, message, {
width: 150, height: 100,
title: "Error",
titleColor: "blue", bgColor: "white", textColor: "black",
icon: "error", modal: true
});
配置对象中的全部属性都是函数可以接受的可选參数,而app和message则是必需要传入的參数。
对于配置对象的处理,能够像以下这样:
function Alert(parent, message, opts) {
opts = opts || {}; // default to an empty options object
this.width = opts.width === undefined ?
320 : opts.width;
this.height = opts.height === undefined
? 240
: opts.height;
this.x = opts.x === undefined
? (parent.width / 2) - (this.width / 2)
: opts.x;
this.y = opts.y === undefined
? (parent.height / 2) - (this.height / 2)
: opts.y;
this.title = opts.title || "Alert";
this.titleColor = opts.titleColor || "gray";
this.bgColor = opts.bgColor || "white";
this.textColor = opts.textColor || "black";
this.icon = opts.icon || "info";
this.modal = !!opts.modal;
this.message = message;
}
对于可选的配置对象,首先使用Item 54中介绍的方法当它在真值推断中返回false时,使用空对象替换它。
上述的代码还有进一步优化的空间:通过使用对象扩展或者合并的函数。
在非常多JavaScript的库和框架中都有一个extend函数,它接受一个目标对象和一个源对象,然后将源对象中的属性复制到目标对象中:
function Alert(parent, message, opts) {
opts = extend({
width: 320,
height: 240
});
opts = extend({
x: (parent.width / 2) - (opts.width / 2),
y: (parent.height / 2) - (opts.height / 2),
title: "Alert",
titleColor: "gray",
bgColor: "white",
textColor: "black",
icon: "info",
modal: false
}, opts);
this.width = opts.width;
this.height = opts.height;
this.x = opts.x;
this.y = opts.y;
this.title = opts.title;
this.titleColor = opts.titleColor;
this.bgColor = opts.bgColor;
this.textColor = opts.textColor;
this.icon = opts.icon;
this.modal = opts.modal;
}
通过extend函数,不再须要时常对每一个属性进行推断。上述代码中的第一个extend函数用来在width和height属性没有被设置使设置默认值,由于在第二个extend函数中会依据它们进行计算。
假设全部的属性终于会被赋值到this对象上,那么以上代码能够简化成以下这样:
function Alert(parent, message, opts) {
opts = extend({
width: 320,
height: 240
});
opts = extend({
x: (parent.width / 2) - (opts.width / 2),
y: (parent.height / 2) - (opts.height / 2),
title: "Alert",
titleColor: "gray",
bgColor: "white",
textColor: "black",
icon: "info",
modal: false
}, opts);
extend(this, opts);
}
extend函数的实现通常都会遍历源对象的属性,然后假设该属性的值不是undefined时,会将它复制到目标对象上:
function extend(target, source) {
if (source) {
for (var key in source) {
var val = source[key];
if (typeof val !== "undefined") {
target[key] = val;
}
}
}
return target;
}
总结
- 使用可选的配置对象来让API更具可读性。
- 配置參数中的属性都应该是函数的可选參数。
- 使用extend工具函数来简化使用了配置对象的代码。
Effective JavaScript Item 55 接受配置对象作为函数參数的更多相关文章
- Effective JavaScript Item 21 使用apply方法调用函数以传入可变參数列表
本系列作为Effective JavaScript的读书笔记. 以下是一个拥有可变參数列表的方法的典型样例: average(1, 2, 3); // 2 average(1); // 1 avera ...
- [c++]基类对象作为函数參数(赋值兼容规则)
编程处理教师的基本情况. 要求: 1.定义一个"person"类.用来存储及处理人的姓名.性别.年龄,成员函数自定: 2.定义"teacher"类,公有继承&q ...
- C++容器类对象函数參数问题
总之中的一个句话:容器类对象作为函数參数,与整数类型作为函数參数的传递特性同样. 验证程序 #include "stdafx.h" #include <iostream> ...
- JavaScript的最大函数參数长度和最大栈深度检測
一般代码也许不会涉及最大參数长度和最大栈深度,但某些特殊场合,检測这两个參数还是有必要的.比如:用递归计算斐波那契数列的第n个值,不了解最大栈深度,难免显得肤浅.又比如:将一串charCode转成St ...
- Effective JavaScript Item 22 使用arguments来创建接受可变參数列表的函数
本系列作为Effective JavaScript的读书笔记. 在Item 21中,介绍了结合apply方法实现的可变參数列表函数average,它实际上仅仅声明了一个数组作为參数,可是利用apply ...
- Effective JavaScript Item 51 在类数组对象上重用数组方法
Array.prototype对象上的标准方法被设计为也能够在其他对象上重用 - 即使不是继承自Array的对象. 因此,在JavaScript中存折一些类数组对象(Array-like Object ...
- Effective JavaScript Item 54 将undefined视为"没有值"
将undefined视为"没有值" JavaScript中的undefined是一个特殊的值:当JavaScript没有提供详细的值时.它就会产生undefined. 比方: 未被 ...
- Effective JavaScript Item 37 认识this的隐式指向
本系列作为Effective JavaScript的读书笔记. CSV数据通常都会被某种分隔符进行分隔.所以在实现CSV Reader时,须要支持不同的分隔符.那么,非常自然的一种实现就是将分隔符作为 ...
- Effective JavaScript Item 38 调用父类的构造函数在子类的构造函数
作为这一系列Effective JavaScript的读书笔记. 在一个游戏或者图形模拟的应用中.都会有场景(Scene)这一概念.在一个场景中会包括一个对象集合,这些对象被称为角色(Actor). ...
随机推荐
- maven 编译指定模块
编译构建指定的模块 mvn clean install -pl model1,model2 -am -Dmaven.test.skip=true
- ACE调试中的一个小问题——ace_main_i无法链接
初学ace没多久,今天遇到了一个小问题. 具体是:我在写完代码之后,编译老是出现一个错误. 提示: ACE_TEST1.obj : error LNK2019: 无法解析的外部符号 "int ...
- 【DB2】NULLS LAST与NULLS FIRST
DB2函数配合 select row_number() over(order by col desc nulls first/nulls last ) as rn,col from table1ord ...
- 【VBA编程】04.使用自定义数据类型
使用自定义数据类型存储输入数据,并通过弹出窗口展示 [代码区域] Type lianxiren ' name As String Sex As String End Type Sub aa() Dim ...
- 利用Redis撤销JSON Web Token产生的令牌
利用Redis撤销JSON Web Token产生的令牌 作者:chszs.版权全部.未经允许,不得转载.博主主页:http://blog.csdn.net/chszs 早先的博文讨论了在Angula ...
- git 教程一
git 是一个开源的分布式版本控件系统,用于敏捷高效地处理任何或小或大的项目. Git是Linus Torvalds为了帮助管理Linux内核开发而开发的一个开放源码的版本控制软件. Git 与常用 ...
- discuz 安装 文件不可写
discuz安装过程中,系统会自动检查环境及文件目录权限,当出现目录不可写: 这个时候只需要用ftp修改文件夹权限就可以了
- 安装Spring+搭建Spring开发环境
https://blog.csdn.net/csdnsjg/article/details/80152815 https://jingyan.baidu.com/article/219f4bf798e ...
- 判断Server Manager里面的Role是否已经安排
用InstallState来判断 function Check-DataDeduplication{ Import-Module "ServerManager" -ErrorAct ...
- [svc]alpha、beta、rc各版本区别
参考:http://www.ttlsa.com/linux/alpha-beta-rc/ 很多软件在正式发布前都会发布一些预览版或者测试版,一般都叫"beta版"或者 " ...