【问题标题】:Wrap static function (IIFE) into prototype将静态函数 (IIFE) 包装到原型中
【发布时间】:2017-09-28 14:40:01
【问题描述】:

我写了一个函数,我以为我只需要处理 1 个对象,但结果我需要超过 1 个。我将使用一个简单的示例:

var Helper = (function () {
    return {
        el: null
        init: function(el) {
            this.el = el;
        }
        doStuff: function(){
            // Modify this.el in someway
        }
    };
}());

那么我只需在页面加载时执行Helper.init(el),然后在需要时运行Helper.doStuff()

现在我有三个需要此功能的元素。

我的第一个想法是让它做Helper.init([el1,el2,el3]) 并让它在一个元素数组上工作,但我可能想分别处理每个元素。

我认为最好的方法可能是将 Helper IIFE 变成一个带有原型的“类”,但我的时间有点紧,所以我正在寻找一种方法来制作一个包装器来完成我所需要的。

我在想我可以只获取函数而不立即执行它,然后以某种方式将该函数存储到原型函数中并以这种方式使用它。

寻找有关如何以最少的代码更改最好地做到这一点的想法。

【问题讨论】:

  • 一开始IIFE有什么原因吗?在您的示例中,您可以将对象分配给Helper
  • “我认为最好的方法是将 Helper IIFE 变成一个带有原型的“类”,但我有点赶时间......” I不会期望它需要很长时间。可能比写问题还少? :-)

标签: javascript class iife


【解决方案1】:

我认为最好的方法可能是将 Helper IIFE 变成带有原型的“类”,但我有点赶时间......

我预计不会花很长时间。

我在想我可以只获取函数而不立即执行它,然后以某种方式将该函数存储到原型函数中并以这种方式使用它。

寻找有关如何以最少的代码更改最好地做到这一点的想法。

类模式只是 JavaScript 中的一种模式,您可以将 Helper 用作其他对象的原型,这符合您的“最小更改”要求。只需使用Object.create

var helper1 = Object.create(Helper);
helper1.init(el);
var helper2 = Object.create(Helper);
helper2.init(el2);
var helper3 = Object.create(Helper);
helper3.init(el3);

// ...
helper1.doStuff();
helper2.doStuff();
helper3.doStuff();

如果你在init的末尾加上return this;,那就更简洁了:

var helper1 = Object.create(Helper).init(el);
var helper2 = Object.create(Helper).init(el2);
var helper3 = Object.create(Helper).init(el3);

// ...
helper1.doStuff();
helper2.doStuff();
helper3.doStuff();

现场示例:

var Helper = (function () {
    return {
        el: null,
        init: function(el) {
            this.el = el;
            return this;
        },
        doStuff: function(){
            this.el.style.color = "green";
            this.el.style.fontWeight = "bold";
        }
    };
}());
var helper1 = Object.create(Helper).init(document.getElementById("el1"));
var helper2 = Object.create(Helper).init(document.getElementById("el2"));
var helper3 = Object.create(Helper).init(document.getElementById("el3"));

// ...
setTimeout(function() {
  helper1.doStuff();
}, 400);
setTimeout(function() {
  helper2.doStuff();
}, 800);
setTimeout(function() {
  helper3.doStuff();
}, 1200);
<div id="el1">el1</div>
<div id="el2">el2</div>
<div id="el3">el3</div>

您甚至可以继续在第一个 el 上直接使用 Helper,进一步减少代码更改,尽管我不推荐这样做。


或者,将它包装在一个返回它的函数中(这里我还包括对init的更改):

function getHelper() {
    var Helper = (function () {
        return {
            el: null,
            init: function(el) {
                this.el = el;
                return this; // <============== Added
            },
            doStuff: function(){
                // Modify this.el in someway
            }
        };
    }());
    return Helper;
}

那么对于你需要的三个地方:

var helper1 = getHelper().init(el);
var helper2 = getHelper().init(el2);
var helper3 = getHelper().init(el2);

// ...
helper1.doStuff();
helper2.doStuff();
helper3.doStuff();

旁注:无论如何,您都不需要 IIFE,除非您在其中包含未在对象初始化程序之外显示的内容...

【讨论】:

    【解决方案2】:

    刚刚重写的代码:

    function Helper (el) {
        this.el = el;
    }
    Helper.prototype = {        
        doStuff: function(){
                // Modify this.el in someway
        }
    };
    
    var helper1 = new Helper(el1);
    var helper2 = new Helper(el2);
    var helper3 = new Helper(el3);
    
    helper1.doStaff();
    helper2.doStaff();
    helper3.doStaff();
    

    【讨论】:

      【解决方案3】:

      另一种方式,从arguments 对象检索参数:

      var Helper = (function () {
          return {
              el: null
              init: function() {
                  this.el = Array.from(arguments)
              }
              doStuff: function(){
                  this.el.forEach(el => {
                      // Modify el in someway
                  });
              }
          };
      }());
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-02-15
        • 1970-01-01
        • 1970-01-01
        • 2018-10-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多