for in 会遍历 原型上的属性
    Object.keys 不会遍历

    Object.defineProperty的缺点。
    缺点 : vm.list = [1, 2, 3, 4];

    1. 通过数组索引值改变数组
      1. vm.list[0] = 2; 通过数组索引来改变值得时候是不会发生变化的。
    2. 对数组长度放生变化
      1. vm.list = [1, 2, 3, 4]; 截取list的长度。不会检测到变化。

    将option中的data 定义到 Vue 实例上

    1. // 通过IIFE立即执行函数来实现模块化。
    2. var Vue = (function (){
    3. // 定义一个构造函数。
    4. var Vue = function (opt){
    5. var vm = this;
    6. this._data = typeof opt.data === 'function'
    7. ? opt.data.call(this)
    8. : typeof opt.data === "Object" && data !==null
    9. ? opt.data
    10. : {};
    11. reactiveData(vm._data, vm);
    12. proxyData(vm,'_data', vm);
    13. }
    14. // 响应式数据。
    15. function reactiveData(data,vm){
    16. var keys = Object.keys(data),
    17. item;
    18. for(var i = 0; i< keys.length; i++){
    19. item = keys[i];
    20. (function(k){
    21. var value = data[k];
    22. Object.defineProperty(data,k,{
    23. get(){
    24. return value
    25. },
    26. set(newVal){
    27. if(newVal === value) return;
    28. value = newVal
    29. }
    30. })
    31. })(item)
    32. }
    33. }
    34. // 将数据代理到实例上
    35. function proxyData(vm,src,data){
    36. var keys = Object.keys(data),
    37. item;
    38. for(var k = 0; k < keys.length; k ++){
    39. item = keys[k];
    40. (function(k){
    41. Object.defineProperty(vm,k,{
    42. get(){
    43. return vm[src][k]
    44. },
    45. set(newValue){
    46. vm[src][k] = newValue
    47. }
    48. })
    49. })(item)
    50. }
    51. }
    52. return Vue
    53. })()