2015-01-23 3 views
0

Может кто-нибудь, пожалуйста, объясните мне, как изменить template.portNumber значение?Значение внутри петли не изменяется

var template = { 
    portNumber: null, 
    stuff: "" 
} 

myfunc(template, 3); 

function myfunc(template, count) { 
    var ports = {} 
    for (var i = 0; i < count; i++) { 
    var portNumber = i + 1; 
    ports[portNumber.toString()] = template; 
    ports[portNumber.toString()].portNumber = portNumber; 
    } 
    console.debug(JSON.stringify(ports, null, 4)); 
    return ports; 
} 

Результат:

"{ 
    "1": { 
     "portNumber": 3, 
     "stuff": "" 
    }, 
    "2": { 
     "portNumber": 3, 
     "stuff": "" 
    }, 
    "3": { 
     "portNumber": 3, 
     "stuff": "" 
    } 
}" 

Ожидаемое:

"{ 
    "1": { 
     "portNumber": 1, 
     "stuff": "" 
    }, 
    "2": { 
     "portNumber": 2, 
     "stuff": "" 
    }, 
    "3": { 
     "portNumber": 3, 
     "stuff": "" 
    } 
}" 

Извините за глупый вопрос, но я действительно застрял с ним. Такой же код хорошо работает в python. Спасибо.

+0

Ваш вопрос уже ответил здесь: http://stackoverflow.com/a/750506/222163 (читай вокруг закрытия в JS) –

+1

@ PaulD'Ambra Это не проблема закрытия. – JJJ

+0

А, нечеткий утренний мозг ... ты совершенно прав @Juhana –

ответ

1

Объект template передается по ссылке, поэтому все элементы относятся к одному объекту. Он заканчивает тем, что выглядит немного как это:

template = {portNumber: 3, stuff: ""}; 
return {ports: {1:template, 2: template, 3: template}} 

Вам нужно clone the object, а затем установить его.

var template = { 
    portNumber: null, 
    stuff: "" 
} 

myfunc(template, 3); 

function myfunc(template, count) { 
    var ports = {} 
    for (var i = 0; i < count; i++) { 
    var portNumber = i + 1; 
    ports[portNumber] = JSON.parse(JSON.stringify(template)); 
    ports[portNumber].portNumber = portNumber; 
    } 
    console.debug(JSON.stringify(ports, null, 4)); 
    return ports; 
} 

Кроме того, вам не нужно вручную указывать числовой ключ, это делается автоматически.

3

Ваш массив заканчивается тем, что имеет три ссылки на один и тот же объект, поэтому каждый раз, когда вы его мутируете, изменение отображается во всех элементах массива.

Дать ports[0].port = "99" волю других слов изменить также ports[1].port потому ports[0] и ports[1] являются тем же объектом.

Вам нужно создать копию объекта вместо ...

3

Причина, по которой весь объект массива является ссылочным типом, указывает только на один экземпляр.

Попробуйте использовать функцию-конструктор, подобную этой.

var template = function(portno, stf){ 
    this.portNumber = portno; 
    this.stuff = stf; 
} 

myfunc(template, 3); 

function myfunc(template, count) { 
    var ports = {} 
    for (var i = 0; i < count; i++) { 
    var portNumber = i + 1; 
    ports[portNumber.toString()] = new template(portNumber , template.stuff); 
    } 
    console.debug(JSON.stringify(ports, null, 4)); 
    return ports; 
} 
+0

'новый шаблон (portno, template.stuff);' должен быть 'новый шаблон (portNumber, template.stuff);'. Кроме того, поскольку вы передаете 'portNumber' в' template', вы можете удалить строку 'ports [portNumber.toString()]. ​​PortNumber = portNumber'. – sloth

+0

@sloth Спасибо за предложение обновленного ответа. –

0

Это справочная проблема.

console.log(myFunc(template, 3)); 
 

 
function myFunc(template, count) { 
 
    var ports = {} 
 
    for (var i = 0; i < count; i++) { 
 
    var portNumber = i + 1; 
 
    ports[portNumber.toString()] = {portNumber:null, stuff:""}; 
 
    ports[portNumber.toString()].portNumber = portNumber; 
 
    } 
 
    // console.debug(JSON.stringify(ports, null, 4)); 
 
    return ports; 
 
}

0

Это потому, что переменная шаблона в функции содержит ссылку на объект шаблона вне вашей функции. Попробуйте это:

function myFunc (template, count) { 
var ports = {}; 
for(var i = 0; i < count; i++) { 
    var portNumber = i + 1; 
    var tmplt = JSON.parse(JSON.stringify(template)); 
    tmplt.portNumber = portNumber; 
    ports[portNumber + ''] = tmplt; 
} 
return ports; 
    } 
Смежные вопросы