array.js 1.7 KB

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