SOURCE

		     		/*Object的变化侦测*/
		//对象的属性拦截
        const arrayProto = Array.prototype;
         const arrayMethods = Object.create(arrayProto);
		function defineReactive(data,key,val){
            if(typeof val === 'object'){
                new Observer(val)
            }
            let childOb = observe(val)
			let dep = new Dep();
			Object.defineProperty(data,key,{
				enumerable:true,
				configurable:true,
				get:function(){
                    // console.log(1)
					dep.depend()
					if(childOb){
                        // console.log("--get--")
                        // console.log(childOb)
						childOb.dep.depend()
					}
					return val;
				},
				set:function(newVal){
                    console.log("--set--")
					if(val === newVal){
						return
					}
					val = newVal
                    dep.notify()
				}
			})
		}
        
        //依赖收集在哪里
		class Dep{
			constructor(){
				this.subs = [];
			}
			addSub(sub){
				this.subs.push(sub)
               
			}
			removeSub(sub){
				remove(this.subs,sub)
			}
			depend(){
				if(window.target){
					this.addSub(window.target)
				}
			}
			notify(){
                // console.log("3-1")
                // console.log(this.subs)
				const subs = this.subs.slice()
                // console.log(subs)
				for(let i =0;i <subs.length;i++){
					subs[i].update()
				}
			}
		}

		function remove(arr,item){
			if(arr.length){
				const index = arr.indexOf(item)
				if(index >-1){
					return arr.splice(index,1)
				}
			}
		}
        //依赖类
        class Watcher {
            constructor(vm,expOrFn,cb){
                // console.log("2-1")
                //vm是数据对象value
                //expOrFn是key
                //cb是回调函数
                this.vm = vm;
                this.getter = parsePath(expOrFn);
                //this.getter为返回函数A
                this.cb = cb;
        
                this.value = this.get();
            }

            get(){
                // console.log(this)
                window.target = this;
                let value = this.getter.call(this.vm,this.vm)
                window.target = undefined;
                return value
            
            }

            update(){
                // console.log("update")
                // console.log(this)
                const oldValue  = this.value;
                // console.log(oldValue)
                this.value = this.get();
                //  console.log(this.value)
                this.cb.call(this.vm,this.value,oldValue)
            }
        }

        const bailRE = /[^\w.$]/;
        function parsePath(path){
            if(bailRE.test(path)){
                return
            }
            const segments = path.split('.')
            //返回函数A 闭包函数
            return function(obj){
                //obj为数据对象value
                //segments为key
                // console.log("2-2")
                // console.log(obj)
                // console.log("-----")
                // console.log(segments)
                for(let i =0;i <segments.length;i++){
                    // console.log("2-3")
                    if(!obj)return
                    //  console.log("2-4")
                    obj = obj[segments[i]]
                }
                // console.log("2-5")
                // console.log(obj)
                return obj
            }
        }
		const hasProto = '__proto__' in {};
		const arrayKeys = Object.getOwnPropertyNames(arrayMethods);
        //侦测所有的key
        class Observer {
            constructor(value){
                this.value = value;
                //数组添加
                	this.dep = new Dep()
                	def(value,'__ob__',this)
                    console.warn(value)
                    console.warn(Array.isArray(value))
                if(Array.isArray(value)){
                	const argument = hasProto?protoAugment:copyAugment;
                	argument(value,arrayMethods,arrayKeys)
                	observeArray(value)
                }
                //数组添加
                if(!Array.isArray(value)){
                    this.walk(value)
                }
            }

            walk(obj){
                const keys = Object.keys(obj)
                for(let i = 0;i<keys.length;i++){
                    defineReactive(obj,keys[i],obj[keys[i]])
                }
            }
        }

        //vue类
        class Vue{
            constructor(options){
                new Observer(options)
                //给数据添加订阅者
                Object.keys(options).forEach(key=>{//按照options的属性循环实例化watcher
                    new Watcher(options,key,()=>{
                        console.log("这是回调方法")
                    });
                })
            }
        }


        // obj.time = "17";
        /**
         * 数据初始化首先 实例化Obsever 并将对象数据作为参数传入 在observer实例中循环参数
         * 对象的值value,并对value调用defineReactive方法中实例化Dep 之后重新定义get和set。
         * get方法中收集依赖 set方法中派发依赖
         * 其次循环数据value 给value添加订阅者 并通过数据项get方法将value 加入dep实例中
         * 
         * **/
         // 数组的变化侦测ss



         ['push','pop','shift','unshift',
  			'splice','sort','reverse'].forEach(function(method){
                  const original = arrayProto[method]
  				def(arrayMethods,method,function(...args){
  					const result = original.apply(this,args)
  					const ob = this.__ob__;
                      console.log("--push--")
  					let inserted
  					switch(method){
  						case 'push':
  						case 'unshift':
  							inserted = args
  							break
  						case 'splice':
  							inserted = args.slice(2)
  							break
  					}
  					if(inserted) observeArray(inserted)
  					ob.dep.notify()
  					return result
  				})

  		})

  			function def(obj,key,val,enumerable){
  				Object.defineProperty(obj,key,{
  					value:val,
  					enumerable:!!enumerable,
  					writable:true,
  					configurable:true
  				})
  			}

  			//Observer类


  			function protoAugment(target,src,keys){
  				target.__proto__ = src;
  			}

  			function copyAugment(target,src,keys){
  				for(let i = 0;i < keys.length;i++){
  					const key = keys[i];

  				}
  			}

  			function observeArray(items){
  				for(let i =0; i < items.length;i++){
  					observe(items[i])
  				}
  			}

  			function observe(value,asRootData){
  				if(!isObject(value)){
  					return
  				}
  				let ob
  				// if(hasOwn(value,'__ob__') && value.__ob__ instanceof Observer ){
  				// 	ob = value.__ob__;
  				// }else{
  				// 	ob = new Observer(value)
  				// }
                  ob = new Observer(value)
  				return ob
  			}

  			function isObject(val) {
                return val != null && typeof val === 'object' 
			//   return val != null && typeof val === 'object' && Array.isArray(val) === false;
			};
        // let obj = {
        //     time:"12",
        //     hour:"21",
        //     secend:20,
        //     street:"灵魂",
        // };
        let obj = {
            array1:[1,3,5,7]
        }
       	// let array1 = [1,3,5,7]
        new Vue(obj)
        // console.log("--1--")
        // console.log(obj.array1[0])
        // console.log(obj.array1[1])
        obj.array1.push(9)
console 命令行工具 X clear

                    
>
console