console.log()
、使っていますか?
最近こんな現象に出くわしました。
$.ajax({
url: url,
type: "GET",
dataType: "json",
data: params,
cache: false,
success: function (response) {
// responseの中身が知りたい
// { hoge: {a:1, b:2, c:3}, fuga: {A:1, B:2, C:3} } みたいな形になっている
console.log(response);
// => { hoge: {a:1, b:2, c:3}, fuga: {A:1, B:2, C:3} }
console.log(response.hoge);
// => { X:1, Y:2, Z:3 } !!!?
// hogeを出力するので {a:1, b:2, c:3} が表示されてほしいのに:(
toDoSomething(response);
},
error: function (){
// ...
}
});
var toDoSomething = function(response) {
// ...
// ...
// to do ...
var hoge = response.hoge;
// fuga = { X:1, Y:2, Z:3 }
response.hoge = fuga;
}
原因
ググればでてくるのですが、例えば👉 console.log()で出力した値が、変わるのはなぜ?
https://teratail.com/questions/61338
デベロッパーツールのコンソールでObjectやArrayなどのオブジェクトを表示する場合、その中身は「console.log()が評価された時」の中身では無く、「コンソール上で表示をさせた時」の中身になります
なので、 toDoSomething
関数でresponseという変数を書き換えているせいで、console.logを行う際に評価する変数の値はすでに書き換えられているタイミングにあるため、このような事象が発生したと考えるべきでしょう。 引数となるresponseという変数を書き換える、処理をそもそも書くなというのはめちゃくちゃ正しいのですしvarは使うなconstを使え、jQuryやめろはまさにそのとおりなんですが作った人のアレがアレでうわなにをすくぁwせdrftgyふじこlp
解決策
Object.assign()
を使うとよいでしょう。Reactしかり、Vueしかり、Angularは知らんけど、JavaScriptのフレームワークは、オブジェクトの変更を検知させるためにこれを使うので、わりと知られているんじゃないかしら。
$.ajax({
url: url,
type: "GET",
dataType: "json",
data: params,
cache: false,
success: function (response) {
const _response = Object.assign({}, response)
console.log(_response);
// => { hoge: {a:1, b:2, c:3}, fuga: {A:1, B:2, C:3} }
const _response_params = Object.assign({}, response.params)
console.log(_response_params);
// => { a:1, b:2, c:3 } , OK!
toDoSomething(response);
},
error: function (){
// ...
}
});
var toDoSomething = function(response) {
// ...
// ...
// to do ...
var hoge = response.hoge;
// fuga = { X:1, Y:2, Z:3 }
response.hoge = fuga;
}
他の解決策としては、JSON.stringify()で文字列化してもよいでしょう。お好きなように。
console.logの挙動にご納得いただけない方は、ぜひGoogleにissueを投げるか(どうやって投げるんやろ...)、patchを送りつけて下さい(どうやって...)。わりとみんな幸せになれるので。