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工具函数来简化使用了配置对象的代码。

  • 相关阅读:
    A1052. Linked List Sorting (25)
    A1032. Sharing (25)
    A1022. Digital Library (30)
    A1071. Speech Patterns (25)
    A1054. The Dominant Color (20)
    A1060. Are They Equal (25)
    A1063. Set Similarity (25)
    电子码表
    矩阵键盘
    对象追踪、临时对象追踪、绝对坐标与相对坐标
  • 原文地址:https://www.cnblogs.com/wzzkaifa/p/7284586.html
Copyright © 2011-2022 走看看