在我的框架上工作时,我想到了一个想法。我正在使用$elect(id).hide()
来选择元素并使用它做任务。没有错。但是,如果我想更改选择器$elect()
并使用其他内容,该怎么办?我必须对文档中的每个$elect
进行罚款并手动替换所有文件。那很无聊。所以我在想是否有可能这样的事情:
var selector = $elect; // or anything else
function [selector](id) {
if (!(this instanceof [selector])) {
return new [selector](id);
}
this.elm = document.getElementById(id);
}
[selector].prototype = {
hide: function () { this.elm.style.display = 'none'; return this; }
}
window.[selector] = [selector];
动态更改功能/对象名称。这将节省大量时间。如果其他人使用该框架,他们可以定义自己的选择器。那不是很好吗?有什么想法吗?
答案 0 :(得分:0)
这个简单的通用模式(我最喜欢的)怎么样?
(function(){ //IIF constructor builder
(this[arguments[0]]= function(/*args*/){ //The constructor
/*constructor payload code*/
}).prototype= { //Methods & Properties to inherit:
method_1: function(){ /*your code*/ } //method 1
, method_2: function(){ /*your code*/ } //method 2
, property_1: /*your code*/ //property 1
, property_2: /*your code*/ //property 2
};
})(/*constructor identifier*/);
this
将引用运行此构建函数的上下文。因此,如果构造函数构建器是针对window
运行的,则window
将具有全局函数$elect
。因此,您也可以在模块化系统中使用此模式。
<小时/> 的更新强>
instanceof
(根据您提供的代码判断,您需要它,以便在调用构造函数时可以省略new
)。 这会让事情变得有点棘手。
就我个人而言,'用户'!=='编码员'和'编码员'(编写代码(使用x库)供用户使用)应该知道何时使用new
。
虽然在开发期间throw new
/ console.log
/ alert
错误可能有用,但在最终(最小化/优化)生产代码中应该没有必要(除非您的论点是是因为你有很多new
语句可以省略,所以你的代码可以进一步缩小。
首先必须决定是否优化
执行速度和使用new
(代码经常运行?):
if(/*called with new*/){
/*constructor payload code*/
} else {
/*error code*/
}
缺少new
以执行速度为代价的或最小的文件大小(代码只运行几次?):
if(!(/*called with new*/)){ /*error code*/ }
/*constructor payload code*/
请注意,如果您打算要求使用new
,那么最后一个选项对于生产代码的注释/删除可能更实用,从而提供最快的执行速度。
行/*called with new*/
可以替换为this instanceof arguments.callee
虽然arguments.callee
是一个很好的通用解决方案(因为没有任何硬编码/命名),但会抛出异常如果你是'use strict';
- 模式,因为它现在在favor of named function expressions中被弃用(出于某种原因)(根据John Resig的说法,未来也可以使用expression this function
)。
MDN specifies that a function name can be used only within the function's body,因此对于严格模式,我们可以命名我们的(以前是匿名的)函数(在以下示例中为C
)
并检查this instanceof C
(而不是this instanceof arguments.callee
):
(function(){ //IIF constructor builder
(this[arguments[0]]= function C(id){ //The constructor
if(!(this instanceof C)){ /*error code*/ } //Catch ID-10-T Error
/*constructor payload code*/
}).prototype= { //Methods & Properties to inherit:
method_1: function(){ /*your code*/ } //method 1
, method_2: function(){ /*your code*/ } //method 2
, property_1: /*your code*/ //property 1
, property_2: /*your code*/ //property 2
};
})('$elect');
如果/*error code*/
仅通过以下方式防止出现无声错误:
alert
/ console.log
/ throw new Error
('Error: forgot new')
然后直到现在这种模式(严格和非严格的变体)是令人难以置信的通用。
如果你想通过返回正确的新对象(除了现在可选的警告编码器)来“修复”调用,那么必须考虑传递给构造函数的参数(如果有的话)。
因此,对于不期望参数的构造函数,您的/*error code*/
应包含:
return new arguments.callee();
表示非严格或
return new C();
严格的
期望(可选)命名参数的构造函数,您的/*error code*/
应该像以下那样硬编码:
return new arguments.callee(arg_1, arg_2 /*,etc..*/);
表示非严格或
return new C(arg_1, arg_2 /*,etc..*/);
严格
例如:
(function(){ //IIF constructor builder
(this[arguments[0]]= function C(id){ //The constructor
if(!(this instanceof C)) return new C(id); //Fix ID-10-T Error
this.elm= document.getElementById(id);
}).prototype= { //Methods & Properties to inherit:
show: function(){ //Method show
this.elm.style.display= '';
}
, hide: function(){ //Method hide
this.elm.style.display= 'none';
}
, toggle: function(){ //Method toggle
this[this.elm.style.display ? 'show' : 'hide']();
}
};
})('$elect');
我目前不知道一种简单而优雅的方法来传递任何(对于firefox来说最多256个)非硬编码的未知(期望/可选/命名)参数(缺少一个单个数组/对象作为第一个参数)。问题是arguments
是一个数组(类似)对象,因此不能像return new C(arguments);
那样简单地传递它
可能会想到.apply()
,因为它接受一组参数作为第二个参数(不像.call()
需要逗号分隔的参数,我们只是试图避免),但是唉:{{1} }和new
/ apply
不能一起使用 1,2 ...(有人,如果你知道的话请发表评论适合这种模式的优雅解决方案,谢谢)
最后是上述模式的一个小变化(和可能的应用)。主要区别在于此模式返回一个构造函数(因此您可以简单地命名引用它的变量)(而不是直接设置构造函数的上述模式):
call
希望这有帮助!