【问题标题】:Inject repetitive code into functions: JavaScript将重复代码注入函数:JavaScript
【发布时间】:2017-08-29 17:46:06
【问题描述】:

下面的add8函数里面有很多for循环。出于这个问题的目的,我已经截断了它,但是我的源代码中的原始函数中有更多的循环。看看:

function select( selector ){
  return document.querySelectorAll( selector );
}

function add8(){
  var x = select( '[ x ]' ), y = select( '[ y ]' ),
    x1 = select( '[ x1 ]' ), y1 = select( '[ y1 ]' ),
    x2 = select( '[ x2 ]' ), y2 = select( '[ y2 ]' ),
    cx = select( '[ cx ]' ), cy = select( '[ cy ]' ),
    i = 0,
    val = 0;

  for( i = 0; i < x.length; i++ ){
    val = x[ i ].getAttribute( 'x' );
    val = Number( val ) + 8;
    x[ i ].setAttribute( 'x', val );
  }  
  for( i = 0; i < y.length; i++ ){
    val = y[ i ].getAttribute( 'y' );
    val = Number( val ) + 8;
    y[ i ].setAttribute( 'y', val );
  }    
  for( i = 0; i < x1.length; i++ ){
    val = x1[ i ].getAttribute( 'x1' );
    val = Number( val ) + 8;
    x1[ i ].setAttribute( 'x1', val );
  }    
  for( i = 0; i < y1.length; i++ ){
    val = y1[ i ].getAttribute( 'y1' );
    val = Number( val ) + 8;
    y1[ i ].setAttribute( 'y1', val );
  }
  // Alot more 'for' loops follow...
}

add8();

您可能会注意到在这些 for 循环中只需要更改几个值,因此我迫切需要一个可以重用大量代码同时使整体代码更短更简洁的函数。

类似

function dynamicFunc( dynamicVar, dynamicStr ) {
  for( i = 0; i < dynamicVar.length; i++ ){
    val = dynamicVar[ i ].getAttribute( dynamicStr );
    val = Number( val ) + 8;
    dynamicVar[ i ].setAttribute( dynamicStr, val );
  } 
}

function add8(){
  var x = select( '[ x ]' ), y = select( '[ y ]' ),
    x1 = select( '[ x1 ]' ), y1 = select( '[ y1 ]' ),
    x2 = select( '[ x2 ]' ), y2 = select( '[ y2 ]' ),
    cx = select( '[ cx ]' ), cy = select( '[ cy ]' ),
    i = 0,
    val = 0;

  dynamicFunc( x, 'x' );
  dynamicFunc( y, 'y' );
  dynamicFunc( x1, 'x1' );
  dynamicFunc( y1, 'y1' );

  // Alot more follow...
}

add8();

自动化那些for 循环,但下面的示例似乎不起作用。我还不太擅长 JS,我想我需要一点帮助。我怎样才能做到这一点?谢谢。

注意:我在源代码中处理了很多 SVG,因此在我的 JavaScript 中选择了属性 xyx1 等。

额外说明:我在这里使用的是香草 JS。

【问题讨论】:

    标签: javascript function variables for-loop automation


    【解决方案1】:

    使用一些 ES6 特性:

    function add8(){
      var attributes = ['x', 'y', 'x1', 'y1']; // all the attributes you care about
      attributes.forEach(attribute => {
        [...select(`[${attribute}]`)].forEach(el => {
          el.setAttribute(attribute, Number(el.getAttribute(attribute)) + 8);
        });
      });
    }
    

    更详细:

    function add8(){
      var attributes = ['x', 'y', 'x1', 'y1']; // all the attributes you care about
      var i, j;
      // loop over the attributes:
      for (i = 0; i < attributes.length; i++) {
        var attribute = attributes[i];
        var elements = select('[' + attribute + ']');
        // loop over the selected elements:
        for (j = 0; j < elements.length; j++) {
          var element = elements[i];
          var val = Number(el.getAttribute(attribute)) + 8;
          el.setAttribute(attribute, val);
        }
      }
    }
    

    【讨论】:

    • 这个例子是否使用了 jQuery?我刚刚看到$ 并想我会问。同样,还不是 JS 的专业人士,抱歉,如果这里很明显。
    • @basement 没有。很好的回答彼得。这真的,真的很好。我超级羡慕你这么快就把它分解成一小段代码的方式。我的答案比 OP 小得多,但不止于此。除了 OP,这在 Internet Explorer 中不起作用,但除此之外它看起来很可靠。
    • 尝试支持至少所有主流浏览器。 @zfrisch 如果得到更好的支持,您应该发布您的答案。优雅是伟大的,但功能是我的首要任务。
    • @zfrisch 不,这是“香草 JavaScript”。你是对的,我的第一个解决方案很简洁,但很难理解。看看第二种方案,应该和第一种是等价的,但是更容易理解,应该适用于所有主流浏览器。
    • @basement 较长的解决方案在 IE 中应该可以正常工作。主要的兼容性问题在于扩展运算符...,Peter 用他更冗长的答案解决了这个问题。你应该准备好了!
    猜你喜欢
    • 1970-01-01
    • 2015-12-28
    • 2011-07-23
    • 2021-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-18
    • 2023-02-02
    相关资源
    最近更新 更多