2016-09-08 1 views
0

Вот мой следующий кодовый блок. Я передаю свой объект val из функции test1 в test2 и измените его значение в test2 и отправьте его обратно.Невозможно понять переменную область в функции JS

var Promise = require("bluebird"); 
var list = [1,2,3]; 

var test1 = function(test) { 
    return new Promise(function(resolve,reject) { 
     var val = {"name" : "my_name","age" : 25}; 
     for (var item in list) { 
      (function (item) { 
       console.log("val",val); 
       test2(val) 
        .then(function(test2Response) { 
         console.log("test2Response",test2Response) 
        }); 
      })(item) 
     } 
    }); 
}; 


var test2 = function(val1) { 
    return new Promise(function(resolve,reject) { 
     console.log("val1",val1) 
     val1.name = val1.name + "_1" 
     resolve(val1) 
    }) 
} 


test1() 

А вот моя ценность моих переменных val и val1 на различных этапах.

val { name: 'my_name', age: 25 } 
val1 { name: 'my_name', age: 25 } 


val { name: 'my_name_1', age: 25 } 
val1 { name: 'my_name_1', age: 25 } 


val { name: 'my_name_1_1', age: 25 } 
val1 { name: 'my_name_1_1', age: 25 } 


test2Response { name: 'my_name_1_1_1', age: 25 } 
test2Response { name: 'my_name_1_1_1', age: 25 } 
test2Response { name: 'my_name_1_1_1', age: 25 } 

Я не мог понять, почему значение Вала изменяется для каждой итерации, даже если я обновляю только val1 не val. Как я могу поддерживать val без изменений и изменять только «val1»?

+1

Объекты javascript передаются по ссылке. try [underscore: 'dupe = _.clone (obj)'] (http://underscorejs.org/#clone) – Plato

+1

Мой плохой я не знал об этом ... Работает как шарм !!!!! Спасибо man –

+0

Ваш 'новый Promise' в' test1' вообще не работает. Вы должны использовать 'Promise.all' – Bergi

ответ

0

Когда вы передаете val в test2, как val1, он по-прежнему остается в памяти. Вы должны были бы клонировать значение, прежде чем перейти к test2, которые можно легко сделать, выполнив, как это перед вызовом test2:

var copyOfVal = Object.assign({}, val) // this just creates a new object using the same contents of val but different references in memory. 

затем передать copyOfVal в test2 и вы получите отдельные результаты.

+0

woa! Кстати, это ES6 – Plato

+0

PS [этот ответ] (http://stackoverflow.com/a/34283281/1380669) упоминает, что этот подход не «глубокий клон», хотя я точно не знаю, что это значит :) – Plato

+1

' _.clone' также является только мелким клоном, все это означает, что если у вас есть объект с вложенными объектами, вложенные объекты не будут клонированы и фактически имеют ту же ссылку, что и исходный объект. Если вы измените одно из вложенных свойств, оно изменится как на оригинал, так и на копию. У Lodash есть '_.cloneDeep (obj)', который рекурсивно клонирует, если вы объект, который соответствует этому шаблону. – finalfreq

Смежные вопросы