Javascript 动态函数/对象名称

Javascript 动态函数/对象名称,javascript,frameworks,Javascript,Frameworks,在研究我的框架时,我想到了一个想法。我正在使用$electid.hide来选择一个元素并对其进行处理。没什么问题。但是,如果我想更改选择器$elect并使用其他东西呢?我必须对文档中的每一个$elect进行罚款,并手动替换它们。那太无聊了。所以我在想,如果这样的事情是可能的: var selector = $elect; // or anything else function [selector](id) { if (!(this instanceof [selector])) {

在研究我的框架时,我想到了一个想法。我正在使用$electid.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*/);
这将引用运行此生成函数的上下文。所以,如果构造函数生成器是针对窗口运行的,那么窗口将具有全局函数$elect。因此,您也可以在模块化系统中使用此模式

更新: 您已经询问了instanceof,根据您提供的代码判断,您需要它,以便在调用构造函数时可以省略new。这会让事情变得有点棘手

对我个人来说,‘用户’!='使用x库编写代码供用户使用的程序员和“程序员”应该知道何时使用新库。 虽然在开发过程中抛出new/console.log/alert error可能会很有用,但在最终最小化/优化的生产代码中应该不需要这样做,除非您的论点是您有许多可以省略的新语句,因此您的代码可以进一步缩小

首先,必须决定是否优化 执行速度和新代码的使用是否经常运行?:

if(/*called with new*/){ 
    /*constructor payload code*/ 
} else { 
    /*error code*/ 
}
还是由于缺少新的、以执行速度为代价的最小文件大小代码只运行几次

if(!(/*called with new*/)){ /*error code*/ } 
/*constructor payload code*/
请注意,如果您想要使用new,那么最后一个选项可能更实用,可以注释掉/删除生产代码,从而提供最快的执行速度

用new*/调用的行/*可以替换为arguments.callee的instanceof。虽然arguments.callee是一个很好的通用解决方案,因为没有硬编码/命名的内容,但如果“使用strict”,它将引发异常-模式,因为在John Resig中或根据John Resig的说法,由于某些原因,它现在已被弃用,因此将来也可以使用

,因此对于严格模式,我们可以在下面的示例中命名以前的匿名函数C 并检查此实例是否为C而不是参数的实例。被调用方:

如果/*错误代码*/仅通过以下方式防止静默错误: alert/console.log/throw new Error“错误:忘记新建” 到目前为止,这种模式无论是严格的还是非严格的变体都是令人麻木的通用模式

如果您想通过向编码器返回正确的新对象(现在可选的警告除外)来“修复”调用,那么必须考虑传递给构造函数的参数(如果有)。 因此,对于不需要参数的构造函数,/*错误代码*/应该包含: 返回新参数.callee;对于非严格或 返回新的C;严格地 如果构造函数需要可选的命名参数,则您的/*错误代码*/应通过硬编码传递它们,如下所示: 返回新参数。calleerg_1、arg_2/*等…*/;对于非严格或 返回新的Carg_1、arg_2/*等;严格地

例如:

(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个非硬编码的未知预期/可选/命名参数,而不是一个数组/对象作为第一个参数。问题是参数是一个类似数组的对象,所以不能像返回新的Carguments那样简单地传递它; .apply-to-rescue您可能会想,因为它接受一系列参数作为第二个参数,而不像.call,它需要逗号分隔的参数,我们只是试图避免,但遗憾的是:new和apply/call不能一起使用。。。有人,如果你知道适合这种模式的优雅解决方案,请留言,谢谢

最后给出了上述模式的一个小变化和可能的应用。主要区别在于,此模式返回构造函数,因此您可以简单地命名引用它的变量,而不是直接设置构造函数的上述模式:

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'
};


希望这有帮助

因此,您希望将属性分配到原型中,但能够动态地选择要将这些属性添加到哪个对象的原型中,或者沿着这些线添加一些属性?类似的。嗯,我也应该能够更改构造函数的名称。使用选择器变量。这是一个很好的解决方案,但与其传入字符串,不如传入对象。例如,functionobj{obj=which;obj.prototype=which;}$elect@GitaarLAB能否在JSFIDLE中用一个方法展示代码的工作示例?@akinuri:done,请参阅更新的答案@JaniHartikainen:为什么这样更好,而且….,我不能让你的例子使用functionobj{obj=whater;obj.prototype=whater;}$elect;在预编var$elect时也不适用;或v ar$elect={};。你能详细说明一下你的方式吗?这两种模式之间的范围/结束链是否存在差异?
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'
};