diff --git a/build/minify.sh b/build/minify.sh
index 6b564e03..d053a6c6 100755
--- a/build/minify.sh
+++ b/build/minify.sh
@@ -12,7 +12,4 @@
 
 # We need to keep dead_code around for now, since the very odd JavaScriptCore
 # scope bug fix (nop().nop()) requires it.
-# TODO: uglifyjs gets confused about Base and Color constructor naming, so we
-# have to tell it to not rename these. It's also not renaming all the local
-# references to classes which could yield a lot of size improvements.
-uglifyjs ../dist/paper.js -o ../dist/paper-min.js -c unsafe=true,unused=false,dead_code=false,hoist_funs=false -m -r "Base,Color,_$_,$_" -b ascii_only=true,beautify=false --comments /^!/
+uglifyjs ../dist/paper.js -o ../dist/paper-min.js -c unsafe=true,unused=false,dead_code=false,hoist_funs=false -m -r "_$_,$_" -b ascii_only=true,beautify=false --comments /^!/
diff --git a/lib/straps.js b/lib/straps.js
index b67b2192..ed23a437 100755
--- a/lib/straps.js
+++ b/lib/straps.js
@@ -83,19 +83,6 @@ var Base = new function() {
 			return _define(obj, name, desc);
 		};
 
-	// Fix Function#name on browsers that do not support it (IE):
-	if (!(function f() {}).name) {
-		define(Function.prototype, 'name', {
-			get: function() {
-				var name = this.toString().match(/^\s*function\s*(\w*)\s*\(/)[1];
-				// For better performance only parse once, and then cache the
-				// result through a new accessor for repeated access.
-				define(this, 'name', { value: name });
-				return name;
-			}
-		});
-	}
-
 	/**
 	 * Private function that injects functions from src into dest, overriding
 	 * (and inherinting from) base.
diff --git a/src/basic/Line.js b/src/basic/Line.js
index 608ba0dd..93e2434b 100644
--- a/src/basic/Line.js
+++ b/src/basic/Line.js
@@ -16,6 +16,8 @@
  * @class The Line object represents..
  */
 var Line = Base.extend(/** @lends Line# */{
+	_class: 'Line',
+
 	// DOCS: document Line class and constructor
 	/**
 	 * Creates a Line object.
diff --git a/src/basic/Matrix.js b/src/basic/Matrix.js
index 4f3eb672..3eef50e7 100644
--- a/src/basic/Matrix.js
+++ b/src/basic/Matrix.js
@@ -38,6 +38,8 @@
  * matrix multiplication).
  */
 var Matrix = Base.extend(/** @lends Matrix# */{
+	_class: 'Matrix',
+
 	/**
 	 * Creates a 2D affine transform.
 	 *
diff --git a/src/basic/Point.js b/src/basic/Point.js
index 07d834c9..259e4fc4 100644
--- a/src/basic/Point.js
+++ b/src/basic/Point.js
@@ -24,6 +24,7 @@
  * console.log(point.y); // 5
  */
 var Point = Base.extend(/** @lends Point# */{
+	_class: 'Point',
 	// Tell Base.read that the Point constructor supports reading with index
 	_readIndex: true,
 
diff --git a/src/basic/Rectangle.js b/src/basic/Rectangle.js
index 8ef9dd9b..479a783f 100644
--- a/src/basic/Rectangle.js
+++ b/src/basic/Rectangle.js
@@ -18,6 +18,7 @@
  * rectangular path, it is not an item.
  */
 var Rectangle = Base.extend(/** @lends Rectangle# */{
+	_class: 'Rectangle',
 	// Tell Base.read that the Rectangle constructor supports reading with index
 	_readIndex: true,
 
diff --git a/src/basic/Size.js b/src/basic/Size.js
index b9282c96..ed57f56e 100644
--- a/src/basic/Size.js
+++ b/src/basic/Size.js
@@ -23,6 +23,7 @@
  * console.log(size.height); // 5
  */
 var Size = Base.extend(/** @lends Size# */{
+	_class: 'Size',
 	// Tell Base.read that the Point constructor supports reading with index
 	_readIndex: true,
 
diff --git a/src/core/Base.js b/src/core/Base.js
index 605ce303..b65b98c9 100644
--- a/src/core/Base.js
+++ b/src/core/Base.js
@@ -36,7 +36,7 @@ Base.inject(/** @lends Base# */{
 	 */
 	toString: function() {
 		return this._id != null
-			?  (this.constructor.name || 'Object') + (this._name
+			?  (this._class || 'Object') + (this._name
 				? " '" + this._name + "'"
 				: ' @' + this._id)
 			: '{ ' + Base.each(this, function(value, key) {
@@ -87,7 +87,7 @@ Base.inject(/** @lends Base# */{
 			// Override Base.extend() to register named classes in Base.exports,
 			// for deserialization and injection into PaperScope.
 			var res = extend.base.apply(this, arguments),
-				name = res.name;
+				name = res.prototype._class;
 			if (name)
 				Base.exports[name] = res;
 			return res;
@@ -300,7 +300,7 @@ Base.inject(/** @lends Base# */{
 						if (!ref) {
 							this.length++;
 							var res = create.call(item),
-								name = item.constructor.name;
+								name = item._class;
 							// Also automatically insert class for dictionary
 							// entries.
 							if (name && res[0] !== name)
@@ -317,7 +317,7 @@ Base.inject(/** @lends Base# */{
 				// If we don't serialize to compact form (meaning no type
 				// identifier), see if _serialize didn't already add the class,
 				// e.g. for classes that do not support compact form.
-				var name = obj.constructor.name;
+				var name = obj._class;
 				if (name && !compact && !res._compact && res[0] !== name)
 					res.unshift(name);
 			} else if (Array.isArray(obj)) {
@@ -326,7 +326,7 @@ Base.inject(/** @lends Base# */{
 					res[i] = Base.serialize(obj[i], options, compact,
 							dictionary);
 				// Mark array as compact, so obj._serialize handling above
-				// doesn't add the constructor name again.
+				// doesn't add the class name again.
 				if (compact)
 					res._compact = true;
 			} else if (Base.isPlainObject(obj)) {
diff --git a/src/core/PaperScope.js b/src/core/PaperScope.js
index 33dad7a3..41ff2578 100644
--- a/src/core/PaperScope.js
+++ b/src/core/PaperScope.js
@@ -33,6 +33,7 @@
  * {@code PaperScope}.
  */
 var PaperScope = Base.extend(/** @lends PaperScope# */{
+	_class: 'PaperScope',
 
 	/**
 	 * Creates a PaperScope object.
diff --git a/src/item/Group.js b/src/item/Group.js
index 71d0a3de..6037f99f 100644
--- a/src/item/Group.js
+++ b/src/item/Group.js
@@ -20,6 +20,7 @@
  * @extends Item
  */
 var Group = Item.extend(/** @lends Group# */{
+	_class: 'Group',
 	_serializeFields: {
 		children: []
 	},
diff --git a/src/item/HitResult.js b/src/item/HitResult.js
index 2bcc9ee5..0c8f220d 100644
--- a/src/item/HitResult.js
+++ b/src/item/HitResult.js
@@ -18,6 +18,8 @@
  * {@link Project#hitTest(point)}.
  */
 var HitResult = Base.extend(/** @lends HitResult# */{
+	_class: 'HitResult',
+
 	initialize: function HitResult(type, item, values) {
 		this.type = type;
 		this.item = item;
diff --git a/src/item/Item.js b/src/item/Item.js
index 6faa9910..a9bc0b3a 100644
--- a/src/item/Item.js
+++ b/src/item/Item.js
@@ -33,14 +33,16 @@ var Item = Base.extend(Callback, /** @lends Item# */{
 				src._serializeFields = Base.merge(
 						this.prototype._serializeFields, src._serializeFields);
 			var res = extend.base.apply(this, arguments),
-				name = res.name;
-			// Derive the _type string from constructor name
+				proto = res.prototype,
+				name = proto._class;
+			// Derive the _type string from class name
 			if (name)
-				res.prototype._type = Base.hyphenate(name);
+				proto._type = Base.hyphenate(name);
 			return res;
 		}
 	},
 
+	_class: 'Item',
 	// All items apply their matrix by default.
 	// Exceptions are Raster, PlacedSymbol, Clip and Shape.
 	_transformContent: true,
@@ -170,8 +172,8 @@ var Item = Base.extend(Callback, /** @lends Item# */{
 		if (!(this instanceof Group))
 			serialize(this._style._defaults);
 		// There is no compact form for Item serialization, we always keep the
-		// type.
-		return [ this.constructor.name, props ];
+		// class.
+		return [ this._class, props ];
 	},
 
 	/**
diff --git a/src/item/Layer.js b/src/item/Layer.js
index 6a9c85aa..32a26832 100644
--- a/src/item/Layer.js
+++ b/src/item/Layer.js
@@ -23,6 +23,8 @@
  * @extends Group
  */
 var Layer = Group.extend(/** @lends Layer# */{
+	_class: 'Layer',
+
 	// DOCS: improve constructor code example.
 	/**
 	 * Creates a new Layer item and places it at the end of the
diff --git a/src/item/PlacedSymbol.js b/src/item/PlacedSymbol.js
index cf7f00c0..86f6d0ca 100644
--- a/src/item/PlacedSymbol.js
+++ b/src/item/PlacedSymbol.js
@@ -19,6 +19,7 @@
  * @extends Item
  */
 var PlacedSymbol = Item.extend(/** @lends PlacedSymbol# */{
+	_class: 'PlacedSymbol',
 	_transformContent: false,
 	// PlacedSymbol uses strokeBounds for bounds
 	_boundsGetter: { getBounds: 'getStrokeBounds' },
diff --git a/src/item/Raster.js b/src/item/Raster.js
index ab28740d..1c22b291 100644
--- a/src/item/Raster.js
+++ b/src/item/Raster.js
@@ -18,6 +18,7 @@
  * @extends Item
  */
 var Raster = Item.extend(/** @lends Raster# */{
+	_class: 'Raster',
 	_transformContent: false,
 	// Raster doesn't make the distinction between the different bounds,
 	// so use the same name for all of them
diff --git a/src/item/Shape.js b/src/item/Shape.js
index 880cbc0b..143108e7 100644
--- a/src/item/Shape.js
+++ b/src/item/Shape.js
@@ -18,6 +18,7 @@
  * @extends Item
  */
 var Shape = Item.extend(/** @lends Shape# */{
+	_class: 'Shape',
 	_transformContent: false,
 
 	initialize: function Shape(type, point, size) {
diff --git a/src/path/CompoundPath.js b/src/path/CompoundPath.js
index 47b77eaa..5de5d8f2 100644
--- a/src/path/CompoundPath.js
+++ b/src/path/CompoundPath.js
@@ -21,6 +21,7 @@
  * @extends PathItem
  */
 var CompoundPath = PathItem.extend(/** @lends CompoundPath# */{
+	_class: 'CompoundPath',
 	_serializeFields: {
 		children: []
 	},
diff --git a/src/path/Curve.js b/src/path/Curve.js
index e79e57b5..c75af1bc 100644
--- a/src/path/Curve.js
+++ b/src/path/Curve.js
@@ -25,6 +25,7 @@
  * tangents at given offsets.
  */
 var Curve = Base.extend(/** @lends Curve# */{
+	_class: 'Curve',
 	/**
 	 * Creates a new curve object.
 	 *
diff --git a/src/path/CurveLocation.js b/src/path/CurveLocation.js
index c93290c2..894fa87c 100644
--- a/src/path/CurveLocation.js
+++ b/src/path/CurveLocation.js
@@ -27,6 +27,7 @@
  * etc.
  */
 var CurveLocation = Base.extend(/** @lends CurveLocation# */{
+	_class: 'CurveLocation',
 	// DOCS: CurveLocation class description: add these back when the  mentioned
 	// functioned have been added: {@link Path#split(location)}
 	/**
diff --git a/src/path/Path.js b/src/path/Path.js
index 95c325e0..9abf148d 100644
--- a/src/path/Path.js
+++ b/src/path/Path.js
@@ -19,6 +19,7 @@
  */
 // DOCS: Explain that path matrix is always applied with each transformation.
 var Path = PathItem.extend(/** @lends Path# */{
+	_class: 'Path',
 	_serializeFields: {
 		segments: [],
 		closed: false
diff --git a/src/path/PathItem.js b/src/path/PathItem.js
index bd2e975a..6aefb168 100644
--- a/src/path/PathItem.js
+++ b/src/path/PathItem.js
@@ -20,6 +20,8 @@
  * @extends Item
  */
 var PathItem = Item.extend(/** @lends PathItem# */{
+	_class: 'PathItem',
+
 	initialize: function PathItem() {
 		Item.apply(this, arguments);
 	},
diff --git a/src/path/Segment.js b/src/path/Segment.js
index 20d86e12..951024bd 100644
--- a/src/path/Segment.js
+++ b/src/path/Segment.js
@@ -23,6 +23,8 @@
  * objects that are connected by this segment.
  */
 var Segment = Base.extend(/** @lends Segment# */{
+	_class: 'Segment',
+
 	/**
 	 * Creates a new Segment object.
 	 *
diff --git a/src/project/Project.js b/src/project/Project.js
index 12bd3fbf..7a94750a 100644
--- a/src/project/Project.js
+++ b/src/project/Project.js
@@ -31,6 +31,7 @@
  * {@link PaperScope#projects} variable.
  */
 var Project = PaperScopeItem.extend(/** @lends Project# */{
+	_class: 'Project',
 	_list: 'projects',
 	_reference: 'project',
 
diff --git a/src/project/Symbol.js b/src/project/Symbol.js
index 02fa7aa7..31446387 100644
--- a/src/project/Symbol.js
+++ b/src/project/Symbol.js
@@ -20,6 +20,8 @@
  * to be updated with every transformation.
  */
 var Symbol = Base.extend(/** @lends Symbol# */{
+	_class: 'Symbol',
+
 	/**
 	 * Creates a Symbol item.
 	 *
@@ -70,7 +72,7 @@ var Symbol = Base.extend(/** @lends Symbol# */{
 
 	_serialize: function(options, dictionary) {
 		return dictionary.add(this, function() {
-			return Base.serialize([this.constructor.name, this._definition],
+			return Base.serialize([this._class, this._definition],
 					options, false, dictionary);
 		});
 	},
diff --git a/src/style/Color.js b/src/style/Color.js
index e9e02054..4d19b873 100644
--- a/src/style/Color.js
+++ b/src/style/Color.js
@@ -275,6 +275,7 @@ var Color = Base.extend(new function() {
 			};
 		}, this);
 	}, /** @lends Color# */{
+		_class: 'Color',
 		// Tell Base.read that the Point constructor supports reading with index
 		_readIndex: true,
 
diff --git a/src/style/Gradient.js b/src/style/Gradient.js
index a61261cb..2dbcca19 100644
--- a/src/style/Gradient.js
+++ b/src/style/Gradient.js
@@ -60,6 +60,8 @@
  * };
  */
 var Gradient = Base.extend(/** @lends Gradient# */{
+	_class: 'Gradient',
+
 	// DOCS: Document #initialize()
 	initialize: function Gradient(stops, radial) {
 		// Define this Gradient's unique id.
diff --git a/src/style/GradientStop.js b/src/style/GradientStop.js
index 8281b815..63b6b2d9 100644
--- a/src/style/GradientStop.js
+++ b/src/style/GradientStop.js
@@ -17,6 +17,8 @@
  * @class The GradientStop object.
  */
 var GradientStop = Base.extend(/** @lends GradientStop# */{
+	_class: 'GradientStop',
+
 	/**
 	 * Creates a GradientStop object.
 	 *
diff --git a/src/style/Style.js b/src/style/Style.js
index 7edaadc5..da814248 100644
--- a/src/style/Style.js
+++ b/src/style/Style.js
@@ -202,6 +202,8 @@ var Style = Base.extend(new function() {
 	Item.inject(item);
 	return fields;
 }, /** @lends Style# */{
+	_class: 'Style',
+
 	initialize: function Style(style, _item) {
 		// We keep values in a separate object that we can iterate over.
 		this._values = {};
diff --git a/src/text/PointText.js b/src/text/PointText.js
index 56430a90..592d5dfd 100644
--- a/src/text/PointText.js
+++ b/src/text/PointText.js
@@ -20,6 +20,8 @@
  * @extends TextItem
  */
 var PointText = TextItem.extend(/** @lends PointText# */{
+	_class: 'PointText',
+
 	/**
 	 * Creates a point text item
 	 *
diff --git a/src/text/TextItem.js b/src/text/TextItem.js
index 2cf907f6..828d2603 100644
--- a/src/text/TextItem.js
+++ b/src/text/TextItem.js
@@ -22,6 +22,7 @@
  * @extends Item
  */
 var TextItem = Item.extend(/** @lends TextItem# */{
+	_class: 'TextItem',
 	_boundsSelected: true,
 	_serializeFields: {
 		content: null
diff --git a/src/tool/Tool.js b/src/tool/Tool.js
index 20298b2d..9314c997 100644
--- a/src/tool/Tool.js
+++ b/src/tool/Tool.js
@@ -43,6 +43,7 @@
  * }
  */
 var Tool = PaperScopeItem.extend(/** @lends Tool# */{
+	_class: 'Tool',
 	_list: 'tools',
 	_reference: '_tool', // PaperScope has accessor for #tool
 	_events: [ 'onActivate', 'onDeactivate', 'onEditOptions',
diff --git a/src/tool/ToolEvent.js b/src/tool/ToolEvent.js
index 644ae70a..ba495543 100644
--- a/src/tool/ToolEvent.js
+++ b/src/tool/ToolEvent.js
@@ -22,6 +22,7 @@
  * @extends Event
  */
 var ToolEvent = Event.extend(/** @lends ToolEvent# */{
+	_class: 'ToolEvent',
 	// Have ToolEvent#item fall back to returning null, not undefined.
 	_item: null,
 
diff --git a/src/ui/CanvasView.js b/src/ui/CanvasView.js
index 6e4aa8ed..2bb01ee0 100644
--- a/src/ui/CanvasView.js
+++ b/src/ui/CanvasView.js
@@ -16,6 +16,8 @@
  * @private
  */
 var CanvasView = View.extend(/** @lends CanvasView# */{
+	_class: 'CanvasView',
+
 	/**
 	 * Creates a view object that wraps a canvas element.
 	 * 
diff --git a/src/ui/Component.js b/src/ui/Component.js
index 1ceda35b..9504df37 100644
--- a/src/ui/Component.js
+++ b/src/ui/Component.js
@@ -15,6 +15,7 @@
   * @class
   */
 var Component = Base.extend(Callback, /** @lends Component# */{
+	_class: 'Component',
 	_events: [ 'onChange', 'onClick' ],
 
 	_types: {
diff --git a/src/ui/Event.js b/src/ui/Event.js
index e4d38e5d..3b4ff68a 100644
--- a/src/ui/Event.js
+++ b/src/ui/Event.js
@@ -15,6 +15,8 @@
  * @class
  */
 var Event = Base.extend(/** @lends Event# */{
+	_class: 'Event',
+
 	initialize: function Event(event) {
 		this.event = event;
 	},
diff --git a/src/ui/KeyEvent.js b/src/ui/KeyEvent.js
index a38f2efb..82f1e88a 100644
--- a/src/ui/KeyEvent.js
+++ b/src/ui/KeyEvent.js
@@ -21,6 +21,8 @@
  * @extends Event
  */
 var KeyEvent = Event.extend(/** @lends KeyEvent# */{
+	_class: 'KeyEvent',
+
 	initialize: function KeyEvent(down, key, character, event) {
 		Event.call(this, event);
 		this.type = down ? 'keydown' : 'keyup';
diff --git a/src/ui/MouseEvent.js b/src/ui/MouseEvent.js
index 64f32684..9c810991 100644
--- a/src/ui/MouseEvent.js
+++ b/src/ui/MouseEvent.js
@@ -23,6 +23,8 @@
  * @extends Event
  */
 var MouseEvent = Event.extend(/** @lends MouseEvent# */{
+	_class: 'MouseEvent',
+
 	initialize: function MouseEvent(type, event, point, target, delta) {
 		Event.call(this, event);
 		this.type = type;
diff --git a/src/ui/Palette.js b/src/ui/Palette.js
index bc1f888a..5bf06f1e 100644
--- a/src/ui/Palette.js
+++ b/src/ui/Palette.js
@@ -15,6 +15,7 @@
   * @class
   */
 var Palette = Base.extend(Callback, /** @lends Palette# */{
+	_class: 'Palette',
 	_events: [ 'onChange' ],
 
 	initialize: function Palette(title, components, values) {
diff --git a/src/ui/View.js b/src/ui/View.js
index 8be7b943..e0116c31 100644
--- a/src/ui/View.js
+++ b/src/ui/View.js
@@ -20,6 +20,8 @@
  * screen.
  */
 var View = Base.extend(Callback, /** @lends View# */{
+	_class: 'View',
+
 	initialize: function View(element) {
 		// Store reference to the currently active global paper scope, and the
 		// active project, which will be represented by this view