Home >Web Front-end >JS Tutorial >Effective JavaScript Item 55 Accept configuration objects as function parameters
Although it is important to maintain the order of parameters accepted by the function, when the number of parameters the function can accept reaches a certain number, it will also cause a headache for users:
var alert = new Alert(100, 75, 300, 200, "Error", message, "blue", "white", "black", "error", true);
As the function continues to be reconstructed and evolved, the parameters it can accept may There will be more and more, and eventually it will look like the example above.
In this case, JavaScript can use a configuration object to replace all the above parameters:
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});
Although this will make the code a little more verbose, there is no doubt that its benefits are obvious: each parameter in the configuration object The name of an attribute is like a document that tells the user what this attribute is used for. Especially for Boolean values, it is difficult to judge its true intention by passing in true and false alone.
Another benefit of using this method is that all attributes are optional. If a property does not appear in the configuration object, the default value is used instead.
var alert = new Alert(); // use all default parameter values
If the function needs to accept necessary parameters, it is best to put it outside the configuration object, like this:
var alert = new Alert(app, message, { width: 150, height: 100, title: "Error", titleColor: "blue", bgColor: "white", textColor: "black", icon: "error", modal: true});
All properties in the configuration object are optional parameters that the function can accept, and app and message are parameters that must be passed in.
For the processing of configuration objects, it can be like the following:
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; }
For optional configuration objects, first use the method introduced in Item 54. When it returns false in the truth value judgment, replace it with an empty object.
The above code still has room for further optimization: by using object expansion or merging functions. There is an extend function in many JavaScript libraries and frameworks, which accepts a target object and a source object, and then copies the properties in the source object to the target object:
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; }
With the extend function, you no longer need to constantly update each attributes to judge. The first extend function in the above code is used to set default values when the width and height properties are not set, because they will be calculated based on them in the second extend function.
If all properties will eventually be assigned to this object, then the above code can be simplified to the following:
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); }
The implementation of the extend function usually traverses the properties of the source object, and then if the value of the property is not undefined, it will Copy it to the target object:
function extend(target, source) { if (source) { for (var key in source) { var val = source[key]; if (typeof val !== "undefined") { target[key] = val; } } } return target; }
Summary
Use optional configuration objects to make the API more readable.
The attributes in the configuration parameters should be optional parameters of the function.
Use the extend utility function to simplify code using configuration objects.