首頁  >  文章  >  web前端  >  Effective JavaScript Item 55 接受配置物件作為函數參數

Effective JavaScript Item 55 接受配置物件作為函數參數

高洛峰
高洛峰原創
2016-11-25 09:18:171210瀏覽

雖然保持函數接受的參數的順序很重要,但是當函數能夠接受的參數達到一定數量時,也會讓用戶很頭疼:

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工具函數來簡化使用了配置物件的程式碼。


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn