みなさん、コウタロウです!!
今日はタイトルについて。
結論から
JavaScriptの代入は参照渡しです。
例)
var obj1 = { aaa: ‘rei’ };
var obj2 = obj1
obj2.aaa = ‘henkou’;
console.log(obj2.aaa); //henkouと表示される
console.log(obj1.aaa); //あれ!? henkouと表示される
ハマりポイント
そういえば何の根拠もなかったが、参照渡しだとは思っていなかった。
現場の仕事でAngularJsのローカルストレージ、セッションストレージを使用しています。
ログイン画面を開きログインするとメニュー画面があり、メニュー画面で各ボタンを押下すると別タブにて遷移先画面が開きます。
別画面(別タブ)でログインした時のユーザー情報を使おうと思ったらセッションストレージはタブが変わると共有できません。
それなのでログインした時のユーザー情報は一旦セッションストレージからローカルストレージに代入して別タブにて、ローカルストレージからセッションストレージに代入し、ローカルストレージの内容はNullにしていました。
つまり、こんな感じ
【メニュー画面】
localStorage.userInfo = sessionStorage.userInfo; //ローカルストレージに代入
【遷移先画面(別タブ)】
sessionStorage.userInfo = localStorage.userInfo;
localStorage.userInfo = null;
これで無事、別タブにユーザー情報を渡すことができ、メニュー画面もユーザー情報を保持していると思っていました。
でも画面動かすと、別タブで参照渡しされたユーザー情報を消してしまったため、メニュー画面でユーザー情報が参照できなくなり、エラーとなる。
オブジェクトの代入が参照渡しだとわかるまで2時間くらいかかってしまいました。。。
回避策
参照渡しではなく、ディープコピーをすることにしました。
【メニュー画面】
//ディープコピー
localStorage.userInfo = angular.copy(sessionStorage.userInfo);
【遷移先画面(別タブ)】
sessionStorage.userInfo = localStorage.userInfo;
//localStorage.userInfo = null; ディープコピーでもnullにするとメニュー画面でもユーザー情報が参照できなくなるのでこの処理もコメント
ディープコピーにすれば別タブでローカルストレージの内容を消しても大丈夫かと思いましたが、消したらメニュー画面で見えなくなったのでやむえず消す処理をコメント化。
最後に
一つ一つの積み重ね。
今回、わかるまで2時間かかりましたが、今回の経験を積むことにより自分のスキルが更に高まりました!!
コメント