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). ...
随机推荐
- winfrom 底层类 验证码
效果图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzgxNjcwOQ==/font/5a6L5L2T/fontsize/400/fill/I ...
- 怎样推断多个字段组成的keyword在另外一张表中是否存在
怎样推断多个字段组成的keyword在另外一张表中是否存在 老帅(20141107) 1.首先推断一个keyword在另外一张表中是否存在非常easy! SELECT * FROM a WHERE a ...
- <译>Flink官方文档-Flink概述
Overview This documentation is for Apache Flink version 1.0-SNAPSHOT, which is the current developme ...
- oracle 查询 函数练习
/*--以下代码是对emp表进行显示宽度设置col empno for 9999;col ename for a10;col job for a10;col mgr for 9999; col hir ...
- python内置函数、匿名函数、递归
python3--内置函数 内置函数: 截止到python 3.6.2 版本,现在python一共提供了68个内置函数:即python提供给你直接可以拿来使用的所有函数. 内置函数 (点击函数查 ...
- Could not create and/or set value back on to object .
严重: Error building beanorg.springframework.beans.factory.UnsatisfiedDependencyException: Error creat ...
- Yii Framework2.0开发教程(3)数据库mysql入门
沿用教程(2)的代码 第一步.在本地mysql数据库中新建数据库zhyoulun 第二步.在数据库中新建表并插入若干条数据 CREATE TABLE `country` ( `code` CHAR(2 ...
- iloc[[i]] 和 loc[[i]] 的区别
In [2]: df Out[2]: A B 0 1.068932 -0.794307 2 -0.470056 1.192211 4 -0.284561 0.756029 6 1.037563 -0. ...
- SSH整合简单例子
说明:简单SSH整合,struts版本2.3.32,spring版本3.2.9,hibernate版本3.6.10 一.开发步骤 1 引jar包,创建用户library.使用的包和之前博文相同,可以参 ...
- 矩阵乘法C语言实现
/* 矩阵乘法C语言实现 Slyar 2009.3.20 */ #include <stdio.h> #include <stdlib.h> /* 给 int 类型定义 ...