构造函数中的JavaScript自定义参数

时间:2017-10-21 13:05:26

标签: javascript class constructor named-parameters

我使用JavaScript( ECMAScript 5 )。我有一个这样的课:

我的班级

function elementClass(htmlType, cssClass, text, value, id) {
    this.htmlType = htmlType;
    this.cssClass = cssClass;
    this.text = text;
    this.value = value;
    this.id = id;
}

有时我需要设置一些属性,我想使用如下代码:

var newElement = new elementClass(htmlType ="div",cssClass = "form-group",id = "div1");

我需要将div1作为id传递,但它作为第三个参数传递。

我可以使用下面的代码来执行此操作:

var newElement3 = new elementClass();
newElement3.htmlType = "div";
newElement3.cssClass = "form-group";
newElement3.id = "div1";  

但我想最小化代码数字,如:

var newElement = new elementClass(htmlType ="div",cssClass = "form-group",id = "div1");

fiddle

我阅读了很多主题,但我无法找到任何解决方案。

有什么办法吗?

谢谢你。

3 个答案:

答案 0 :(得分:2)

将对象作为参数传递:

function ElementClass ( settings ){
  for(var key in settings){
    this[key] = settings[key];
  }     
}

所以你可以这样做:

var instance = new ElementClass({
  some:"other"
});

如果您想要默认参数/阻止扩展,您可以这样做:

function ElementClass( options ){
  var defaults = {
    some:"value"
    stays:"the same"
  };

  for(var key in defaults){
    this[key] = options[key] || defaults[key];
  }
}

所以如果你实例化它:

 new ElementClass({
   some:"stuff", //overridden
   whatever:"unknown" //omitted
 });

它会导致

{ some:"stuff", stays:"the same"}

答案 1 :(得分:0)

执行此操作的一种简单方法是传入自定义对象,而不是传递单独的不同参数。

创建接口(可选)

您可以在打字文件中添加一个接口声明,以便您的智慧。

interface ElementSettings {
    htmlType: string;
    cssClass: string;
    value: string;
    text: string;
    id: string;
}

更改班级

/** @param {ElementSettings} settings */
function ElementClass(settings) {
    // Throws an error if function is called without new
    if (!(this instanceof ElementClass)) {
        throw new TypeError("Cannot call a class as a function");
    }
    // Discards invalid input
    settings = settings instanceof Object ? settings : {};
    this.htmlType = settings.htmlType || "Default type";
    this.cssClass = settings.cssClass || "Default class";
    this.value = settings.value || "Default value";
    this.text = settings.text || "Default text";
    this.id = settings.id || "Default id";
}

// This can now be called using: 

new ElementClass({
    cssClass: "item",
    text: "Hello World"
});

使用默认对象

您可以代替让|| "Default Value"到处都有默认设置对象,并将其与设置参数合并。

var ElementClass = (function() {
    var defaultSettings = {
        htmlType: "Default Type",
        cssClass: "Default Class",
        value: "Default Value",
        text: "Default Text",
        id: "Default Id"
    };

    /** @param {ElementSettings} settings */
    function ElementClass(settings) {
        // Throws an error if function is called without new
        if (!(this instanceof ElementClass)) {
            throw new TypeError("Cannot call a class as a function");
        }
        // Discards invalid input
        settings = settings instanceof Object ? settings : {};
        // In ES6 you could use Object.assign
        for (var property in defaultSettings) {
            this[property] = settings[property] || defaultSettings[property];
        }
    }

    return ElementClass;    
})();

实施例

var ElementClass = (function () {
    var defaultSettings = {
        htmlType: "div",
        cssClass: "Default Class",
        value: "Default Value",
        text: "Default Text",
        id: "Default Id"
    };

    function ElementClass(settings) {
        if (!(this instanceof ElementClass)) throw new TypeError("Cannot call a class as a function");
        settings = settings instanceof Object ? settings : {};
        for (var property in defaultSettings) this[property] = settings[property] || defaultSettings[property];
        this.getDom = function getDom() {
            var dom = document.createElement(this.htmlType);
            dom.className = this.cssClass;
            dom.textContent = this.text;
            dom.value = this.cssClass;
            dom.id = this.id;
            return dom;
        };
    }

    return ElementClass;
})();

var form = document.querySelector("form");
var container = document.querySelector("#item-container");
form.addEventListener("submit", function (evt) {
    var formData = form.querySelectorAll("input:not([type='submit'])");
    var settings = {};
    formData.forEach(function (formItem) {
        var value = formItem.value;
        var name = formItem.getAttribute("name");
        if (value && name) settings[name] = value;
    });
    container.appendChild(new ElementClass(settings).getDom());
    evt.preventDefault();
});
#item-container>* {
background-color: rgba(100, 100, 100, 9.4);
min-width: 20px
min-height: 20px;
}
<form action="#">
  <input type="text" name="htmlType" placeholder="HTML Type" />
  <input type="text" name="cssClass" placeholder="CSS Class" />
  <input type="text" name="value" placeholder="Value" />
  <input type="text" name="text" placeholder="Text" />
  <input type="text" name="id" placeholder="Id" />
  <input type="submit" value="Create Object" />
</form>
<div id="item-container">

</div>

一些注释

JavaScript类命名约定为UpperCamelCase,因此您应该ElementClass而不是elementClass。检查Class是使用new还是作为函数调用也是一个好主意。因此,如果您执行ElementClass({})而不是new ElementClass({}),则会抛出Exception。最后,我将default settings ObjectIIFE一起包裹在ElementClass中,以便其他脚本不会访问/更改它。

答案 2 :(得分:0)

您的代码似乎已经使用默认参数,您也可以使用速记属性名称并返回object和rest参数以获取最初未定义的任何属性

function elementClass({
  htmlType = "" // defaults to empty string
, cssClass = "" // defaults to empty string
, text = "" // defaults to empty string
, value = "" // defaults to empty string
, id = "" // defaults to empty string
, ...rest // handle any other properties passed as parameters
}) {
    return {htmlType, cssClass, text, value, id, ...rest}
}

$("#new1").click(function() {
    var newElement1 = new elementClass({
                        htmlType:"div"
                      , cssClass:"form-group"
                      , id:"div1"
                      , otherData:123
                      });
    showElement(newElement1);    
});

jsfiddle https://jsfiddle.net/3r8a6gbq/2/