Vue.jsのレンダリングがどうなってるか調べてみたけど、、、

## 背景

`id`, `class`も振らずにどうやってレンダリングしてるんだろ？と思い、どんな実装になってるのか調べてみた。`jQuery`などで`DOM`操作してた感覚からすると不思議だったので。
Vueのバージョンは`2.5.17`になります。

```html
<!DOCTYPE html>
<script src="./vue2.5.17.js"></script>

<div id="app"></div>

<script>
  const vm = new Vue({
    template: '<p>{{ msg }}</p>',
    data: { msg: 'hello world!' }
  }).$mount('#app')
</script>
```

このように実装してみて、`defineReactive`にブレークポイント設定してみると以下の順に処理されてることがわかった。


```js:Vue
function Vue (options) {
   // options = {template: "<p>{{ msg }}</p>", data: {…}}
  ...
  this._init(options);
}
```

```js:_init
Vue.prototype._init = function (options) {
  // vm = Vue {_uid: 0, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue, …}
  var vm = this;
  ...
  initState(vm);
  ...
};
```

```js:initState
function initState (vm) {
  ...
  // opts = {components: {…}, directives: {…}, filters: {…}, _base: ƒ, template: "<p>{{ msg }}</p>", …}
  var opts = vm.$options;
  ...
  if (opts.data) {
    initData(vm);
  }
  ...
}
```

```js:initData
function initData (vm) {
  // data = {msg: "hello world!", __ob__: Observer}
  var data = vm.$options.data;
  data = vm._data = typeof data === 'function'
    ? getData(data, vm)
    : data || {};
  ...
  observe(data, true /* asRootData */);
}
```

```js:observe
function observe (value, asRootData) {
  ...
  var ob;
  if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
    ob = value.__ob__;
  } else if (
    shouldObserve &&
    !isServerRendering() &&
    (Array.isArray(value) || isPlainObject(value)) &&
    Object.isExtensible(value) &&
    !value._isVue
  ) {
    // value = {msg: "hello world!", __ob__: Observer}
    ob = new Observer(value);
  }
  ...
  return ob
}
```

```js:Observer
var Observer = function Observer (value) {
  this.value = value;
  ...
  if (Array.isArray(value)) {
    ...
  } else {
    // value = {msg: "hello world!", __ob__: Observer}
    this.walk(value);
  }
};
```

```js:walk
Observer.prototype.walk = function walk (obj) {
  // obj = {msg: "hello world!", __ob__: Observer}
  var keys = Object.keys(obj); // keys = ["msg"]
  for (var i = 0; i < keys.length; i++) {
    defineReactive(obj, keys[i]);
  }
};
```

```js:defineReactive
function defineReactive (
  obj, // obj = {msg: "hello world!", __ob__: Observer}
  key, // key = "msg"
  val,
  customSetter,
  shallow
) {
  var dep = new Dep(); // dep = Dep {id: 3, subs: Array(0)}
  // property = {value: "hello world!", writable: true, enumerable: true, configurable: true}, obj = {msg: "hello world!", __ob__: Observer}, key = "msg"
  var property = Object.getOwnPropertyDescriptor(obj, key);
  if (property && property.configurable === false) {
    return
  }

  // cater for pre-defined getter/setters
  var getter = property && property.get;
  if (!getter && arguments.length === 2) {
    val = obj[key];
  }
  var setter = property && property.set;

  var childOb = !shallow && observe(val);
  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function reactiveGetter () {
      var value = getter ? getter.call(obj) : val;
      if (Dep.target) {
        dep.depend();
        if (childOb) {
          childOb.dep.depend();
          if (Array.isArray(value)) {
            dependArray(value);
          }
        }
      }
      return value
    },
    set: function reactiveSetter (newVal) {
      var value = getter ? getter.call(obj) : val;
      /* eslint-disable no-self-compare */
      if (newVal === value || (newVal !== newVal && value !== value)) {
        return
      }
      /* eslint-enable no-self-compare */
      if ("development" !== 'production' && customSetter) {
        customSetter();
      }
      if (setter) {
        setter.call(obj, newVal);
      } else {
        val = newVal;
      }
      childOb = !shallow && observe(newVal);
      dep.notify();
    }
  });
}
```

`defineReactive`で`msg`にゲッター・セッターを持たせてるようです。
そこで、

```js
vm.msg = 'こんにちは世界！'
```
とすると、`defineReactive`で設定したセッターが反応して

```js:defineReactive
dep.notify();
```
によりウォッチャに通知が行くみたいです。そこでウォッチャがレンダリング関数を呼び出してレンダリングされるようですが、結局このレンダリング関数を読み解かないと`id`、`class`なしでレンダリングできてる不思議は解決しなさそうだなと思ったところで力尽きました。
この記事は[千 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/sen)の23日目の予定でしたが、過ぎた上に調べきれてなくすみません。
近々続きを書きたいと思います。