retlat's blog

Vue.jsとReactのマウント動作比べ

仕事で使うのがVue.jsばかりだったのでReactとどう違うのか見てみる
とりあえずマウントした時の動作を

環境はVue.jsが 2.6.11 、Reactは 16.13.1

土台はこんな感じのHTMLで

<body>
  <div id="app">
    <span>Loading...</span>
  </div>
</body>

まずはVue.jsから
ソースはこんな感じで

new Vue({
  el: '#app',
  render(h) {
    return h('div', 'Hello, World!');
  }
});

実行した結果はこうなってて、 div#app が消えてる

<body>
  <div>Hello, World!</div>
</body>

次にReactで、ソースはこう

ReactDOM.render(
  React.createElement('div', null, 'Hello, World!'),
  document.querySelector('#app')
);

結果は div#app > span は消えるけど、 div#app は残ってる

<body>
  <div id="app"><div>Hello, World!</div></div>
</body>

VueReactどちらもドキュメントを読んだら書いてあるので、ちゃんと読むのは大事

Array.prototype.mapとshallow copy

Arrayのdeep copyはどう作るのかなと思ってArray.prototype.map()を触っていたら、パッと思ったのと挙動が違うのでメモ
環境はSafari 13.0.5

まずArray.prototype.map()はMDNには以下のように記載されている

map() メソッドは、与えられた関数を配列のすべての要素に対して呼び出し、その結果からなる新しい配列を生成します。

ということで雑にcallbackFnで引数をそのまま返してみる

const a = [{a: 'aaa'}];
const b = a.map(v => v);

b[0].a = 'bbb';

console.log(a, b);
// Array (1)
//   0 {a: "bbb"}
// Array (1)
//   0 {a: "bbb"}

あれ? 新しいArrayが生成されるのに変数aの値も変わってる?
いや、Arrayとしては新しく生成されたけど、要素単位ではobjectだからshallow copyされてる?
ということでプリミティブ値のArrayで実験

const a = ['aaa'];
const b = a.map(v => v);

b[0] = 'bbb';

console.log(a, b);
// Array (1)
//   0 "aaa"
// Array (1)
//   0 "bbb"

変数aの方には影響が出なかったので、やっぱり要素がobjectだとそこだけはshallow copyみたい
ということは型の混ざるArrayだと?

const a = ['aaa', {a: 'aaa'}];
const b = a.map(v => v);

b[0] = 'bbb';
b[1].a = 'ccc';

console.log(a, b);
// Array (2)
//   0 "aaa"
//   1 {a: "ccc"}
// Array (2)
//   0 "bbb"
//   1 {a: "ccc"}

思った通りに混ざった
代入の仕様そのままだけど思い込みで違和感たっぷり