Javascript:包装类(在ES5中)

时间:2018-02-02 23:39:56

标签: javascript ecmascript-5

现在我有大约3个单独的javascript"类"。我称他们为这样;

ajax(parameters).success().error()
getElement('selector').height(400).width(400).remove();
customAlert({object with arguments});

这不仅感觉像是随机函数调用,而且可能会给我一些命名问题。 然后我想:jQuery如何做到这一点? 好吧,我不知道。我试过谷歌搜索主题,但到目前为止,我还没有找到任何如何实现这一目标的结果。只有如何添加原型等的结果......

我班级的基本想法是这样的:

var getElement = function(selector){
  if(!(this instanceof getElement))
  {
      return new getElement(selector);
  }

  //Do element getting

  return this;
};

getElement.prototype = {
  name: function,
  name: function,
  //etc.
};

现在,这种工作非常好,但我希望"前缀"并将我的函数放在包装类中。我想这样称呼我的函数:

wrap.getElement(selector);
wrap.ajax(parameters).success().error();
wrap.customAlert({object with arguments});

然而,每当我尝试时,我都会遇到至少一种错误或问题,例如;

  • 在我的课程中失去this范围
  • 无法将prototype个功能添加到我的课程
  • 整个包装类通过每个函数调用重新实现
  • 无法创建new object()因为范围不再正确

另外,如果可能的话,我希望每次都不重新初始化包装类。 (看起来非常低效,对吗?)

所以我想要一个包装类的实例,而其中的类获取它们的新实例并且只是做它们的事情。这甚至是可能还是我只是在这里做梦?

这是我迄今为止尝试过的方式;

//It would probably be easier to use an object here, but I want it to
//default to wrap.getElement(selector) when it's just wrap(selector),
//without re-instantiating the old class
var wrap = function(selector){
  //Check if docready and such here
}

wrap.prototype.getElement = function(){
 // the getElement class here
}
//This is where it starts going wrong. I can't seem to re-add the prototypes 
//back to the getElement class this way.
wrap.getElement.prototype = {
  name:function,
  name:function,
  //etc
}
//I can call wrap().getElement(); now, but not the prototypes of 
  getElement().
//Also, I still have wrap() while I'd want wrap.getElement.

然后我"解决了#34;通过先将变量放入变量来进行wrap()的问题。

var test = new wrap();
test.getElement(selector); // works and only inits once!
//However, I did have to remove the 'new instance' from my getElement()

我也尝试过这种方式,但这只是在错误的基础上给了我错误,而我并不知道为什么;

(function(wrap) {
  console.log("init")
  this.getElement = function() {
    return "test";
  };
})(wrap);
// Gives me "wrap is undefined" etc.

最后但并非最不重要的是,我已经尝试过这种方式了;

var wrap = new function() {
  return this;
};

wrap.getElement = function(){};
//This works perfectly fine
wrap.getElement.prototype.css = function(){};
//This will cause "getElement.css is not a function"

所以是的,我有点被困在这里。我发现,在ES6中有很多方法可以解决这个问题。然而,我不愿意转到ES6(因为我不会使用任何仍然需要翻译的东西)。所以它必须是ES5。

1 个答案:

答案 0 :(得分:1)

将模块包装在命名空间中并保持类完好无损的最简单方法是使用“Revealing模块模式”。

它使用一个立即调用的函数表达式(IIFE)来设置具有私有作用域的所有函数,然后只返回一个新对象中的函数(它作为模块的命名空间)

var wrap = (function() {
  function getElement() {...}
  function moreFunctions() {...}
  function etcFuncitons() {...}

  return {
    getElement: getElement,
    moreFunctions: moreFunctions,
    etcFuncitons: etcFuncitons
 };
})();

回答你的第二个问题

  

我希望能够自己调用wrap()。我希望它自动转发到getElement()。这很难吗?这种结构有可能吗?因为这看起来很容易维护,我很乐意保持它像你的答案。 - 现在它将回复wrap()不是函数

我没有对此进行测试,但您应该能够将函数直接附加到返回的包装函数。这应该通过将共享this添加到原型

来避免共享var wrap = (function() { function getElement() {...} function moreFunctions() {...} function etcFuncitons() {...} function wrap(selector) { return new getElement(selector); } wrap.getElement = getElement; wrap.moreFunctions = moreFunctions; wrap.etcFuncitons = etcFuncitons; return wrap; }; })(); 的问题
dbHandle = dbReference?.child("lang").observe(.childAdded,  with:{(snapshot) in

    guard let dictionary = snapshot.value as? [String:Any],
    let de = dictionary["de"] as? String, 
    let en = dictionary["en"] as? String else {
    "error occurs when down casting.."
     return}

   self.outputone.text = de
   self.outputwo.text = en 
})

这是有效的,因为一切都是javascript中的对象,甚至函数哈哈