JavaScript对象上的动态方法

Dynamic methds on JavaScript Object

本文关键字:动态 方法 对象 JavaScript      更新时间:2023-09-26

我试图在JavaScript中创建一个简单的HTML标签引擎。我们的想法是使用标记名作为函数名,但是为了做到这一点,函数不必被实现。让我们假设它存在于一个名为HTML的对象中。

应该是这样的:

HTML.h1({class:"uberheadline"}, "Hello World");
HTML.div({id:"megabox"});

到目前为止,我有一个非常基本的实现是:

function create_and_append_html_element(params) {
  var attributes = params.attr;
  var tag = params.tag;
  var target = params.target;
  var content = params.content;
  var element = document.createElement(tag);
  if (attributes) $(element).attr(attributes);
  if (content) $(element).html(content);
  if (target) $(target).append(element);
  return element;
}

本质上,我想这样运行一个函数,只是不需要指定tag变量。这可能吗?如果是这样,从哪里开始寻找答案呢?

您必须编写逻辑来推断tag的值,如果它没有传递给您的函数

如果你想通过字符串名动态调用一个方法,你可以这样做:

HTML.h1({class:"uberheadline"}, "Hello World");
HTML.div({id:"megabox"});
var methodToCall = 'h1';
if(typeof(HTML[methodToCall]) === 'function') {
    HTML[methodToCall](); // run function
}

如果我理解正确的话,你想让HTML.h1这样的函数在内部调用create_and_append_html_element,并自动设置tag属性。

为此,您可以创建如下函数:

// array of elements separated with space
$.each("h1 div".split(" "), function(i, tag) {
    // make the function available as HTML.h1, HTML.div, etc.
    HTML[tag] = function(attr, content) {
        return create_and_append_html_element({ tag:     tag  // pass tag through
                                                attr:    attr,
                                                content: content });
    };
});

我不知道确切的语法和那些HTML.h1函数的签名是什么(看起来像(attr, content)),但你当然可以改变它。

好吧,我很无聊,所以我试了一下。最后一行是你想要得到的。

  // Using a tag whitelist
  var tags = [
     'div', 'b', 'a', 'i', 'link', 'script', 'p', 'em', 'span' // ... and so on
  ]
  // HTML constructor
  function _HTML() {
  }
  // Your magic create/append function
  function create_append(tagname, params) {
     params.target.append (document.createElement(tagname));
  };
  // Patch prototype with one closure per tag name in whitelist
  for (var i=0; i<tags.length; i++) {
     var tagname = tags[i];
     _HTML.prototype[tagname] = function(tagname) {
        return function (params) {
           return create_append(tagname, params);
        }
     }(tagname);
  }
  // Export user-accessible object
  var HTML = new _HTML;
  // Now you can do this!
  HTML.div({target:$('body')});

完整的jsFiddle在这里。