Javascript:包装器 class(在 ES5 中)
Javascript: A wrapper class (in ES5)
现在我有大约 3 个独立的 javascript "classes"。我这样称呼他们;
ajax(parameters).success().error()
getElement('selector').height(400).width(400).remove();
customAlert({object with arguments});
这不仅感觉像是随机函数调用,而且可能会给我带来一些命名问题。
然后我想:jQuery
是怎么做到的呢?
好吧,我不知道。我试过用谷歌搜索这个主题,但到目前为止我还没有找到任何关于如何实现这一目标的结果。只有如何添加原型等的结果...
我的classes的基本思路是这样的:
var getElement = function(selector){
if(!(this instanceof getElement))
{
return new getElement(selector);
}
//Do element getting
return this;
};
getElement.prototype = {
name: function,
name: function,
//etc.
};
现在,这工作得很好,但我想 "prefix" 并将我的函数范围限定在包装器 class 中。我想这样调用我的函数:
wrap.getElement(selector);
wrap.ajax(parameters).success().error();
wrap.customAlert({object with arguments});
但是,每当我尝试时,我都会遇到至少一种错误或问题,例如;
- 在我的 classes
中失去 this
范围
- 无法将
prototype
函数添加到我的 classes
- 整个包装器 class 在每次函数调用时重新实例化
- 无法创建
new object()
因为范围不再正确
此外,如果可能的话,我希望不要每次都重新初始化 包装器class。 (看起来效率极低,对吧?)
所以我想要包装器 class 的 1 个实例,而其中的 classes 获得它们的新实例并只做它们的事情。这是可能的还是我只是在做梦?
这是我迄今为止尝试过的方法;
//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.
然后我 "solved" 必须首先将它放入变量中来完成 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.
将模块包装在命名空间中并保持 类 完整的最简单方法是使用 "Revealing module pattern".
它使用立即调用的函数表达式 (IIFE) 来设置所有具有私有作用域的函数,然后 returns 只设置新对象中的函数(作为模块的命名空间)
var wrap = (function() {
function getElement() {...}
function moreFunctions() {...}
function etcFuncitons() {...}
return {
getElement: getElement,
moreFunctions: moreFunctions,
etcFuncitons: etcFuncitons
};
})();
回答你的第二个问题
I would like to be able to call wrap() by itself as well. I want it to forward automatically to getElement(). Is this hard to do? Is this possible with this construction? Because this looks very easy to maintain and I'd love to keep it like your answer. - Right now it will reply wrap() is not a function
我还没有对此进行测试,但您应该能够将函数直接附加到返回的包装函数。这应该通过将它们添加到原型
来避免共享 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;
};
})();
这是可行的,因为在 javascript 中一切都是对象,甚至函数哈哈
现在我有大约 3 个独立的 javascript "classes"。我这样称呼他们;
ajax(parameters).success().error()
getElement('selector').height(400).width(400).remove();
customAlert({object with arguments});
这不仅感觉像是随机函数调用,而且可能会给我带来一些命名问题。
然后我想:jQuery
是怎么做到的呢?
好吧,我不知道。我试过用谷歌搜索这个主题,但到目前为止我还没有找到任何关于如何实现这一目标的结果。只有如何添加原型等的结果...
我的classes的基本思路是这样的:
var getElement = function(selector){
if(!(this instanceof getElement))
{
return new getElement(selector);
}
//Do element getting
return this;
};
getElement.prototype = {
name: function,
name: function,
//etc.
};
现在,这工作得很好,但我想 "prefix" 并将我的函数范围限定在包装器 class 中。我想这样调用我的函数:
wrap.getElement(selector);
wrap.ajax(parameters).success().error();
wrap.customAlert({object with arguments});
但是,每当我尝试时,我都会遇到至少一种错误或问题,例如;
- 在我的 classes 中失去
- 无法将
prototype
函数添加到我的 classes - 整个包装器 class 在每次函数调用时重新实例化
- 无法创建
new object()
因为范围不再正确
this
范围
此外,如果可能的话,我希望不要每次都重新初始化 包装器class。 (看起来效率极低,对吧?)
所以我想要包装器 class 的 1 个实例,而其中的 classes 获得它们的新实例并只做它们的事情。这是可能的还是我只是在做梦?
这是我迄今为止尝试过的方法;
//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.
然后我 "solved" 必须首先将它放入变量中来完成 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.
将模块包装在命名空间中并保持 类 完整的最简单方法是使用 "Revealing module pattern".
它使用立即调用的函数表达式 (IIFE) 来设置所有具有私有作用域的函数,然后 returns 只设置新对象中的函数(作为模块的命名空间)
var wrap = (function() {
function getElement() {...}
function moreFunctions() {...}
function etcFuncitons() {...}
return {
getElement: getElement,
moreFunctions: moreFunctions,
etcFuncitons: etcFuncitons
};
})();
回答你的第二个问题
I would like to be able to call wrap() by itself as well. I want it to forward automatically to getElement(). Is this hard to do? Is this possible with this construction? Because this looks very easy to maintain and I'd love to keep it like your answer. - Right now it will reply wrap() is not a function
我还没有对此进行测试,但您应该能够将函数直接附加到返回的包装函数。这应该通过将它们添加到原型
来避免共享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;
};
})();
这是可行的,因为在 javascript 中一切都是对象,甚至函数哈哈