From 64002a90832f4f6ae8ac1f885eb2dde06a3cbaf8 Mon Sep 17 00:00:00 2001 From: Andrew Dupont Date: Fri, 23 May 2008 13:30:17 -0500 Subject: [PATCH] Fix toString/valueOf sharing same method reference via closure in Class#addMethods. Use plain property assignment, since Object.extend fails to enumerate over toString/valueOf. --- CHANGELOG | 2 ++ src/base.js | 11 ++++++----- test/unit/base_test.js | 11 +++++++++++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 06ea003..67dc3c6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,5 @@ +* Fix toString/valueOf sharing same method reference via closure in Class#addMethods. Use plain property assignment, since Object.extend fails to enumerate over toString/valueOf. (kangax) + * Stop Form.Element.disable from stealing focus. (jddalton) * Ensure Element.hide and Element.show return an element, even if you pass an element ID. (Andrew Dupont) diff --git a/src/base.js b/src/base.js index 3074e2e..df1b97e 100644 --- a/src/base.js +++ b/src/base.js @@ -44,12 +44,13 @@ Class.Methods = { var property = properties[i], value = source[property]; if (ancestor && Object.isFunction(value) && value.argumentNames().first() == "$super") { - var method = value, value = Object.extend((function(m) { + var method = value; + value = (function(m) { return function() { return ancestor[m].apply(this, arguments) }; - })(property).wrap(method), { - valueOf: function() { return method }, - toString: function() { return method.toString() } - }); + })(property).wrap(method); + + value.valueOf = method.valueOf.bind(method); + value.toString = method.toString.bind(method); } this.prototype[property] = value; } diff --git a/test/unit/base_test.js b/test/unit/base_test.js index 6624cac..9b13849 100644 --- a/test/unit/base_test.js +++ b/test/unit/base_test.js @@ -498,6 +498,17 @@ new Test.Unit.Runner({ valueOf: function() { return "valueOf" } }); + var Parent = Class.create({ + m1: function(){ return 'm1' }, + m2: function(){ return 'm2' } + }); + var Child = Class.create(Parent, { + m1: function($super) { return 'm1 child' }, + m2: function($super) { return 'm2 child' } + }); + + this.assert(new Child().m1.toString().indexOf('m1 child') > -1); + this.assertEqual("toString", new Foo().toString()); this.assertEqual("valueOf", new Foo().valueOf()); }