zoukankan      html  css  js  c++  java
  • 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;
    }

    总结

    1. 使用可选的配置对象来让API更具可读性。
    2. 配置參数中的属性都应该是函数的可选參数。

    3. 使用extend工具函数来简化使用了配置对象的代码。

  • 相关阅读:
    Jmeter连接数据库并使用数据表数据作为接口所需参数
    使用CSV Data Set Config配置原件,参数化数据
    Jmeter连接SqlServer数据库并操作
    jmeter导入jmx文件报错:missing class com.thoughtworks.xstream.converters.ConversionException
    jmeter请求参数的两种方式
    badboy录制,出现弹框提示脚本错误解决方法
    (三)LoadRunner术语认识
    (二)LoadRunner目录分析
    7z命令
    python复制多层目录下的文件至其他盘符对应的目录中
  • 原文地址:https://www.cnblogs.com/wzzkaifa/p/7284586.html
Copyright © 2011-2022 走看看