在我的框架上工作时,我想到了一个主意。我$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];
动态更改功能/对象名称。这样可以节省大量时间。如果其他人要使用该框架,则他们可以定义自己的选择器。那不是很好吗?有任何想法吗?
那么这个简单的通用模式(我的最爱)呢?
(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
将引用运行此构建功能的上下文。因此,如果构造函数builder与相对应window
,window
则将具有全局功能$elect
。因此,您也可以在模块化系统中使用此模式。
instanceof
(并根据提供的代码来判断,您需要它,以便 new
在调用构造函数时可以忽略它 )。 这会使事情变得有些棘手。
就我个人而言,'users'!=='coders'和'coders'(谁编写代码(使用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
是一个很好的通用解决方案(因为没有硬编码/命名),但如果您使用-mode,它将抛出异常'use strict';
,因为(由于某种原因)现在不推荐使用它,而是使用命名函数表达式(并且根据对约翰·雷西格(John Resig)来说,将来也可以使用该表达方式this function
)。
MDN指定一个函数名称只能在该函数的主体内使用,因此对于严格模式,我们可以命名我们的(以前是匿名的)函数(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()
需要逗号分隔的参数不同,我们只是试图避免),但很可惜:new
和apply
/call
不能一起使用的1,2 ...(有人,请发表评论,如果你知道一个优雅的解决方案,在这种模式的配合,谢谢)
最后,对上述模式进行很小的改动(以及可能的应用)。主要区别在于此模式返回一个构造函数(因此您可以简单地命名引用它的变量)(而不是上面的直接设置该构造函数的模式):
var myLibrary= {
$elect: (function(C){
(C= function(id){
if(!(this instanceof C)) return new C(id);
this.elm= document.getElementById(id);
}).prototype= {
addBorder: function(col){
this.elm.style.border='1px solid '+col;
}
, delBorder: function(){
this.elm.style.border='';
}
}; return C;
})()
, var_foo: 'foo'
, var_bar: 'bar'
};
希望这可以帮助!
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句