github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/public/libs/vue-1.0.24/src/observer/array.js (about) 1 import { def, indexOf } from '../util/index' 2 3 const arrayProto = Array.prototype 4 export const arrayMethods = Object.create(arrayProto) 5 6 /** 7 * Intercept mutating methods and emit events 8 */ 9 10 ;[ 11 'push', 12 'pop', 13 'shift', 14 'unshift', 15 'splice', 16 'sort', 17 'reverse' 18 ] 19 .forEach(function (method) { 20 // cache original method 21 var original = arrayProto[method] 22 def(arrayMethods, method, function mutator () { 23 // avoid leaking arguments: 24 // http://jsperf.com/closure-with-arguments 25 var i = arguments.length 26 var args = new Array(i) 27 while (i--) { 28 args[i] = arguments[i] 29 } 30 var result = original.apply(this, args) 31 var ob = this.__ob__ 32 var inserted 33 switch (method) { 34 case 'push': 35 inserted = args 36 break 37 case 'unshift': 38 inserted = args 39 break 40 case 'splice': 41 inserted = args.slice(2) 42 break 43 } 44 if (inserted) ob.observeArray(inserted) 45 // notify change 46 ob.dep.notify() 47 return result 48 }) 49 }) 50 51 /** 52 * Swap the element at the given index with a new value 53 * and emits corresponding event. 54 * 55 * @param {Number} index 56 * @param {*} val 57 * @return {*} - replaced element 58 */ 59 60 def( 61 arrayProto, 62 '$set', 63 function $set (index, val) { 64 if (index >= this.length) { 65 this.length = Number(index) + 1 66 } 67 return this.splice(index, 1, val)[0] 68 } 69 ) 70 71 /** 72 * Convenience method to remove the element at given index or target element reference. 73 * 74 * @param {*} item 75 */ 76 77 def( 78 arrayProto, 79 '$remove', 80 function $remove (item) { 81 /* istanbul ignore if */ 82 if (!this.length) return 83 var index = indexOf(this, item) 84 if (index > -1) { 85 return this.splice(index, 1) 86 } 87 } 88 )