Javascript Array Concat não funciona. Por quê?

92

Então, criei este widget jqueryui. Isso cria uma div para a qual posso transmitir erros. O código do widget é parecido com este:

$.widget('ui.miniErrorLog', {
   logStart: "<ul>",   // these next 4 elements are actually a bunch more complicated.
   logEnd:   "</ul>",
   errStart: "<li>",
   errEnd:   "</li>",
   content:  "",
   refs:     [],

   _create: function() { $(this.element).addClass( "ui-state-error" ).hide(); },

   clear: function() { 
      this.content = ""; 
      for ( var i in this.refs )
         $( this.refs[i] ).removeClass( "ui-state-error" );
      this.refs = [];
      $(this.element).empty().hide(); 
   }, 

   addError: function( msg, ref ) {
      this.content += this.errStart + msg + this.errEnd; 
      if ( ref ) {
         if ( ref instanceof Array )
            this.refs.concat( ref );
         else
            this.refs.push( ref );
         for ( var i in this.refs )
            $( this.refs[i] ).addClass( "ui-state-error" );
      }
      $(this.element).html( this.logStart + this.content + this.logEnd ).show();
   }, 

   hasError: function()
   {
      if ( this.refs.length )
         return true;
      return false;
   },
});

Posso adicionar mensagens de erro a ele e referências a elementos de página que serão colocados em um estado de erro. Eu o uso para validar diálogos. No método "addError" posso passar um único id, ou uma matriz de ids, assim:

$( "#registerDialogError" ).miniErrorLog( 
   'addError', 
   "Your passwords don't match.", 
   [ "#registerDialogPassword1", "#registerDialogPassword2" ] );

Mas quando eu passo em uma série de ids, não funciona. O problema está nas seguintes linhas (eu acho):

if ( ref instanceof Array )
   this.refs.concat( ref );
else
   this.refs.push( ref );

Por que esse concat não funciona? this.refs e ref são arrays. Então, por que o concat não funciona?

Bônus: estou fazendo mais alguma coisa idiota neste widget? É o meu primeiro.

Rafael baptista
fonte

Respostas:

260

O método concat não altera o array original, você precisa reatribuí-lo.

if ( ref instanceof Array )
   this.refs = this.refs.concat( ref );
else
   this.refs.push( ref );
Alcides Queiroz Aguiar
fonte
5
Isso foi o suficiente. Eu teria pensado que um método concat em um objeto seria anexado ao objeto. Mas acho que não é assim que funciona.
Rafael Baptista
3
@Rafael: O pushmétodo faz isso, você poderia fazer[].push.apply(this.refs, ref)
Bergi,
78

Aqui está o motivo:

Definição e Uso

O método concat () é usado para unir dois ou mais arrays.

Este método não altera os arrays existentes, mas retorna um novo array, contendo os valores dos arrays unidos.

Você precisa atribuir o resultado da concatenação de volta ao array que você possui.

Konstantin Dinev
fonte
2
Por que, oh por que, devo sempre esquecer isso?
Jeff Lowery de
9

Para expandir em Konstantin Dinev:

.concat()não adiciona ao objeto atual, então isso não funcionará:

foo.bar.concat(otherArray);

Isso vai:

foo.bar = foo.bar.concat(otherArray);
mewc
fonte
4

você tem que reatribuir o valor usando = para a matriz, que deseja obter o valor concatenado

let array1=[1,2,3,4];
let array2=[5,6,7,8];

array1.concat(array2);
console.log('NOT WORK :  array1.concat(array2); =>',array1);

array1= array1.concat(array2);
console.log('WORKING :  array1 = array1.concat(array2); =>',array1);

Saurabh Mistry
fonte
1
dataArray = dataArray.concat(array2)
PRATHYUSH P
fonte