Evan You 11 лет назад
Родитель
Сommit
5a19bf75ff

+ 21 - 7
src/observe/array-augmentations.js

@@ -17,8 +17,8 @@ var arrayAugmentations = Object.create(Array.prototype)
 .forEach(function (method) {
   // cache original method
   var original = Array.prototype[method]
-  // define wrapped method
-  _.define(arrayAugmentations, method, function () {
+
+  function mutator () {
     // avoid leaking arguments:
     // http://jsperf.com/closure-with-arguments
     var l = arguments.length
@@ -79,7 +79,13 @@ var arrayAugmentations = Object.create(Array.prototype)
     })
 
     return result
-  })
+  }
+  // define wrapped method
+  if (_.hasProto) {
+    _.define(arrayAugmentations, method, mutator)
+  } else {
+    arrayAugmentations[method] = mutator
+  }
 })
 
 /**
@@ -91,12 +97,12 @@ var arrayAugmentations = Object.create(Array.prototype)
  * @return {*} - replaced element
  */
 
-_.define(arrayAugmentations, '$set', function (index, val) {
+function $set (index, val) {
   if (index >= this.length) {
     this.length = index + 1
   }
   return this.splice(index, 1, val)[0]
-})
+}
 
 /**
  * Convenience method to remove the element at given index.
@@ -105,13 +111,21 @@ _.define(arrayAugmentations, '$set', function (index, val) {
  * @param {*} val
  */
 
-_.define(arrayAugmentations, '$remove', function (index) {
+function $remove (index) {
   if (typeof index !== 'number') {
     index = this.indexOf(index)
   }
   if (index > -1) {
     return this.splice(index, 1)[0]
   }
-})
+}
+
+if (_.hasProto) {
+  _.define(arrayAugmentations, '$set', $set)
+  _.define(arrayAugmentations, '$remove', $remove)
+} else {
+  arrayAugmentations.$set = $set
+  arrayAugmentations.$remove = $remove
+}
 
 module.exports = arrayAugmentations

+ 12 - 4
src/observe/object-augmentations.js

@@ -10,7 +10,7 @@ var objectAgumentations = Object.create(Object.prototype)
  * @public
  */
 
-_.define(objectAgumentations, '$add', function $add (key, val) {
+function $add (key, val) {
   if (this.hasOwnProperty(key)) return
   // make sure it's defined on itself.
   _.define(this, key, val, true)
@@ -19,7 +19,7 @@ _.define(objectAgumentations, '$add', function $add (key, val) {
   ob.convert(key, val)
   ob.emit('add:self', key, val)
   ob.propagate('add', key, val)
-})
+}
 
 /**
  * Deletes a property from an observed object
@@ -29,12 +29,20 @@ _.define(objectAgumentations, '$add', function $add (key, val) {
  * @public
  */
 
-_.define(objectAgumentations, '$delete', function $delete (key) {
+function $delete (key) {
   if (!this.hasOwnProperty(key)) return
   delete this[key]
   var ob = this.$observer
   ob.emit('delete:self', key)
   ob.propagate('delete', key)
-})
+}
+
+if (_.hasProto) {
+  _.define(objectAgumentations, '$add', $add)
+  _.define(objectAgumentations, '$delete', $delete)
+} else {
+  objectAgumentations.$add = $add
+  objectAgumentations.$delete = $delete
+}
 
 module.exports = objectAgumentations

+ 2 - 1
src/observe/observer.js

@@ -44,7 +44,8 @@ function Observer (value, type, options) {
       this.link(value)
     } else if (type === OBJECT) {
       if (options && options.doNotAlterProto) {
-        _.deepMixin(value, objectAugmentations)
+        _.define(value, '$add', objectAugmentations.$add)
+        _.define(value, '$delete', objectAugmentations.$delete)
       } else {
         _.augment(value, objectAugmentations)
       }

+ 1 - 1
src/parse/template.js

@@ -9,7 +9,7 @@ var map = {
     2,
     '<table><tbody></tbody><colgroup>',
     '</colgroup></table>'
-  ],
+  ]
 }
 
 map.td =

+ 9 - 18
src/util/lang.js

@@ -90,21 +90,6 @@ exports.extend = function (to, from) {
   }
 }
 
-/**
- * Mixin including non-enumerables, and copy property
- * descriptors.
- *
- * @param {Object} to
- * @param {Object} from
- */
-
-exports.deepMixin = function (to, from) {
-  Object.getOwnPropertyNames(from).forEach(function (key) {
-    var desc =Object.getOwnPropertyDescriptor(from, key)
-    Object.defineProperty(to, key, desc)
-  })
-}
-
 /**
  * Proxy a property on one object to another.
  *
@@ -172,14 +157,20 @@ exports.define = function (obj, key, val, enumerable) {
 /**
  * Augment an target Object or Array by either
  * intercepting the prototype chain using __proto__,
- * or copy over property descriptors
+ * or copy over properties with defineProperty.
  *
  * @param {Object|Array} target
  * @param {Object} proto
  */
 
-exports.augment = '__proto__' in {}
+var define = exports.define
+var hasProto = exports.hasProto = '__proto__' in {}
+exports.augment = hasProto
   ? function (target, proto) {
       target.__proto__ = proto
     }
-  : exports.deepMixin
+  : function (target, proto) {
+      for (var key in proto) {
+        define(target, key, proto[key])
+      }
+    }

+ 5 - 34
test/unit/specs/util/lang_spec.js

@@ -58,36 +58,6 @@ describe('Util - Language Enhancement', function () {
     expect(to.b).toBe(from.b)
   })
 
-  it('deepMixin', function () {
-    var from = Object.create({c:123})
-    var to = {}
-    Object.defineProperty(from, 'a', {
-      enumerable: false,
-      configurable: true,
-      get: function () {
-        return 'AAA'
-      }
-    })
-    Object.defineProperty(from, 'b', {
-      enumerable: true,
-      configurable: false,
-      value: 'BBB'
-    })
-    _.deepMixin(to, from)
-    var descA = Object.getOwnPropertyDescriptor(to, 'a')
-    var descB = Object.getOwnPropertyDescriptor(to, 'b')
-
-    expect(descA.enumerable).toBe(false)
-    expect(descA.configurable).toBe(true)
-    expect(to.a).toBe('AAA')
-
-    expect(descB.enumerable).toBe(true)
-    expect(descB.configurable).toBe(false)
-    expect(to.b).toBe('BBB')
-
-    expect(to.c).toBeUndefined()
-  })
-
   it('proxy', function () {
     var to = { test2: 'to' }
     var from = { test2: 'from' }
@@ -140,13 +110,14 @@ describe('Util - Language Enhancement', function () {
   })
 
   it('augment', function () {
+    var target = {}
+    var proto = { a: 1 }
+    _.augment(target, proto)
     if ('__proto__' in {}) {
-      var target = {}
-      var proto = {}
-      _.augment(target, proto)
       expect(target.__proto__).toBe(proto)
     } else {
-      expect(_.augment).toBe(_.deepMixin)
+      expect(Object.keys(target).length).toBe(0)
+      expect(target.a).toBe(1)
     }
   })