Просмотр исходного кода

use native Set when available for tracking deps

Evan You 10 лет назад
Родитель
Сommit
8971027f80
2 измененных файлов с 36 добавлено и 10 удалено
  1. 23 0
      src/util/env.js
  2. 13 10
      src/watcher.js

+ 23 - 0
src/util/env.js

@@ -104,3 +104,26 @@ export const nextTick = (function () {
     timerFunc(nextTickHandler, 0)
   }
 })()
+
+let _Set
+/* istanbul ignore if */
+if (typeof Set !== 'undefined' && Set.toString().match(/native code/)) {
+  // use native Set when available.
+  _Set = Set
+} else {
+  // a non-standard Set polyfill that only works with primitive keys.
+  _Set = function () {
+    this.set = Object.create(null)
+  }
+  _Set.prototype.has = function (key) {
+    return this.set[key] !== undefined
+  }
+  _Set.prototype.add = function (key) {
+    this.set[key] = 1
+  }
+  _Set.prototype.clear = function () {
+    this.set = Object.create(null)
+  }
+}
+
+export { _Set }

+ 13 - 10
src/watcher.js

@@ -7,7 +7,8 @@ import {
   warn,
   isArray,
   isObject,
-  nextTick
+  nextTick,
+  _Set as Set
 } from './util/index'
 
 let uid = 0
@@ -47,8 +48,8 @@ export default function Watcher (vm, expOrFn, cb, options) {
   this.dirty = this.lazy // for lazy watchers
   this.deps = []
   this.newDeps = []
-  this.depIds = Object.create(null)
-  this.newDepIds = null
+  this.depIds = new Set()
+  this.newDepIds = new Set()
   this.prevError = null // for async error stacks
   // parse expression for getter/setter
   if (isFn) {
@@ -163,8 +164,6 @@ Watcher.prototype.set = function (value) {
 
 Watcher.prototype.beforeGet = function () {
   Dep.target = this
-  this.newDepIds = Object.create(null)
-  this.newDeps.length = 0
 }
 
 /**
@@ -175,10 +174,10 @@ Watcher.prototype.beforeGet = function () {
 
 Watcher.prototype.addDep = function (dep) {
   var id = dep.id
-  if (!this.newDepIds[id]) {
-    this.newDepIds[id] = true
+  if (!this.newDepIds.has(id)) {
+    this.newDepIds.add(id)
     this.newDeps.push(dep)
-    if (!this.depIds[id]) {
+    if (!this.depIds.has(id)) {
       dep.addSub(this)
     }
   }
@@ -193,14 +192,18 @@ Watcher.prototype.afterGet = function () {
   var i = this.deps.length
   while (i--) {
     var dep = this.deps[i]
-    if (!this.newDepIds[dep.id]) {
+    if (!this.newDepIds.has(dep.id)) {
       dep.removeSub(this)
     }
   }
+  var tmp = this.depIds
   this.depIds = this.newDepIds
-  var tmp = this.deps
+  this.newDepIds = tmp
+  this.newDepIds.clear()
+  tmp = this.deps
   this.deps = this.newDeps
   this.newDeps = tmp
+  this.newDeps.length = 0
 }
 
 /**