Skip to content

Commit 5590378

Browse files
committed
simplify array change detection
1 parent 1a35cf4 commit 5590378

File tree

3 files changed

+14
-64
lines changed

3 files changed

+14
-64
lines changed

src/runtime/observer/index.js

+1-39
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
1+
import './patch-array'
12
import Dep from './dep'
2-
import { arrayMethods } from './array'
33
import {
44
def,
55
isArray,
66
isObject,
77
isPlainObject,
8-
hasProto,
98
hasOwn
109
} from '../util/index'
1110

12-
const arrayKeys = Object.getOwnPropertyNames(arrayMethods)
13-
1411
/**
1512
* By default, when a reactive property is set, the new value is
1613
* also converted to become reactive. However in certain cases, e.g.
@@ -43,10 +40,6 @@ export function Observer (value) {
4340
this.dep = new Dep()
4441
def(value, '__ob__', this)
4542
if (isArray(value)) {
46-
var augment = hasProto
47-
? protoAugment
48-
: copyAugment
49-
augment(value, arrayMethods, arrayKeys)
5043
this.observeArray(value)
5144
} else {
5245
this.walk(value)
@@ -118,37 +111,6 @@ Observer.prototype.removeVm = function (vm) {
118111
this.vms.$remove(vm)
119112
}
120113

121-
// helpers
122-
123-
/**
124-
* Augment an target Object or Array by intercepting
125-
* the prototype chain using __proto__
126-
*
127-
* @param {Object|Array} target
128-
* @param {Object} src
129-
*/
130-
131-
function protoAugment (target, src) {
132-
/* eslint-disable no-proto */
133-
target.__proto__ = src
134-
/* eslint-enable no-proto */
135-
}
136-
137-
/**
138-
* Augment an target Object or Array by defining
139-
* hidden properties.
140-
*
141-
* @param {Object|Array} target
142-
* @param {Object} proto
143-
*/
144-
145-
function copyAugment (target, src, keys) {
146-
for (var i = 0, l = keys.length; i < l; i++) {
147-
var key = keys[i]
148-
def(target, key, src[key])
149-
}
150-
}
151-
152114
/**
153115
* Attempt to create an observer instance for a value,
154116
* returns the new observer if successfully observed,

src/runtime/observer/array.js src/runtime/observer/patch-array.js

+13-22
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,18 @@
1-
import { def } from '../util/index'
1+
import { def, toArray } from '../util/index'
22

33
const arrayProto = Array.prototype
4-
export const arrayMethods = Object.create(arrayProto)
4+
const mutationMethods = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse']
55

66
/**
7-
* Intercept mutating methods and emit events
7+
* Intercept mutating methods and notify change
88
*/
99

10-
;[
11-
'push',
12-
'pop',
13-
'shift',
14-
'unshift',
15-
'splice',
16-
'sort',
17-
'reverse'
18-
]
19-
.forEach(function (method) {
10+
mutationMethods.forEach(function (method) {
2011
// cache original method
2112
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-
}
13+
14+
var interceptor = function arrayMutationInterceptor () {
15+
var args = toArray(arguments)
3016
var result = original.apply(this, args)
3117
var ob = this.__ob__
3218
var inserted
@@ -45,7 +31,12 @@ export const arrayMethods = Object.create(arrayProto)
4531
// notify change
4632
ob.dep.notify()
4733
return result
48-
})
34+
}
35+
36+
arrayProto[method] = function () {
37+
let fn = this && this.__ob__ ? interceptor : original
38+
return fn.apply(this, arguments)
39+
}
4940
})
5041

5142
/**

src/runtime/util/env.js

-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
/* global MutationObserver */
22

3-
// can we use __proto__?
4-
export const hasProto = '__proto__' in {}
5-
63
// Browser environment sniffing
74
export const inBrowser =
85
typeof window !== 'undefined' &&

0 commit comments

Comments
 (0)