Prev: How to link CSS(s) already linked to parent frame into child iframe using javascript
Next: Error getElementbyClassName
From: Thomas 'PointedEars' Lahn on 13 Jan 2010 09:20 Dmitry A. Soshnikov wrote: > Thomas 'PointedEars' Lahn wrote: >> Dmitry A. Soshnikov wrote: >> > David Mark wrote: >> >> > By the way, there's also one more ability to call overwritten >> >> > parent method just with `this._super()' expression. >> >> >> >> I assume you mean this._super.foo() to call the "super" foo method. >> > >> > Actually, just this._super(), e.g. >> > >> > foo: function () { >> > this._super(); // will call `foo' in parent >> > } >> Never. Check your assumptions. > > Please remember this ;) And your asking to show to you something that > you don't know. If you want, I can show you the code. Please do. I would be very much surprised if it worked as you posted. For that would require that the method was called as a method of itself. PointedEars -- Use any version of Microsoft Frontpage to create your site. (This won't prevent people from viewing your source, but no one will want to steal it.) -- from <http://www.vortex-webdesign.com/help/hidesource.htm> (404-comp.)
From: Dmitry A. Soshnikov on 13 Jan 2010 09:41 On Jan 13, 5:20 pm, Thomas 'PointedEars' Lahn <PointedE...(a)web.de> wrote: > Dmitry A. Soshnikov wrote: > > Thomas 'PointedEars' Lahn wrote: > >> Dmitry A. Soshnikov wrote: > >> > David Mark wrote: > >> >> > By the way, there's also one more ability to call overwritten > >> >> > parent method just with `this._super()' expression. > > >> >> I assume you mean this._super.foo() to call the "super" foo method. > > >> > Actually, just this._super(), e.g. > > >> > foo: function () { > >> > this._super(); // will call `foo' in parent > >> > } > >> Never. Check your assumptions. > > > Please remember this ;) And your asking to show to you something that > > you don't know. If you want, I can show you the code. > > Please do. I would be very much surprised if it worked as you posted. > For that would require that the method was called as a method of itself. > This is just a copy-paste of my theoretical thoughts based on well- known patterns (with intermediate constructor to make prototype chain and with wrappers for methods with the same name). Main goals of the code bellow: * No optimization; * No whatever; * scope chain of wrapped methods and wrapper will have some garbage; * I *don't* use this pattern (and have never used) in production, this is *just academical interest*; * I don't like this pattern, it's just to show alternative. File for constructors ("classes") building, you can call it Class.js or whatever: --------------------------------- function Class(params) { function Klass() { this.initialize.apply(this, arguments); } if (params.__extends) { var __inheritance = function () {}; __inheritance.prototype = params.__extends.prototype; Klass.prototype = new __inheritance(); Klass.prototype.constructor = Klass; Klass.superClass = params.__extends; } !params.initialize && (params.initialize = Class.emptyFn); Klass.prototype.__class__ = Klass; for (var method in params) if (params.hasOwnProperty(method)) { if (method == '__extends') { continue; } Klass.prototype[method] = params[method]; if (params.__extends && typeof params.__extends.prototype[method] == 'function') { (function (methodName) { var __originalMethod = params[methodName]; var __superMethod = params.__extends.prototype[methodName]; Klass.prototype[methodName] = function () { var __previousSuper = this._super; this._super = __superMethod; var result = __originalMethod.apply(this, arguments); this._super = __previousSuper; return result; }; })(method); } } return Klass; } Class.emptyFn = function () {}; --------------------------------- So, nothing special, all of this you all know. Usage. File for testing: --------------------------------- <script type="text/javascript" src="Class.js"></script> <script type="text/javascript"> var A = Class({ initialize: function (aArg) { this.aArg = aArg; alert('A#initialize'); }, test: function () { alert('A#test'); } }); var B = Class({ __extends: A, initialize: function (bArg) { this._super(bArg); this.bArg = bArg; alert('B#initialize'); }, test: function () { this._super(); alert('B#test'); } }); var C = Class({ __extends: B, initialize: function (cArg) { this._super(cArg); this.cArg = cArg; alert('C#initialize'); }, test: function () { this._super(); alert('C#test'); } }); var D = Class({ __extends: C, initialize: function (dArg) { this._super(dArg); this.dArg = dArg; alert('D#initialize'); }, test: function () { this._super(); alert('D#test'); this.testD(); }, testD: function () { alert('D#testD'); } }); var d = new D(10); d.test(); --------------------------------- You can see how `d' instance is created and how parent methods are called (alerts will inform about this). The code is complete and runnable. But as I said, I don't like this implementation much as it's not so useful from the performance. Regarding to implementation with `caller' which also will let to use just `this.super()', I haven't yet code, will write later if will be needed (but can tell, that only difference will be in marking methods to set their `name' property, which is used in Spidermonkey's implementation. Using that ability we can call parent methods by name, using `caller' from the `this._super()', quit easy and elegant, but dangerous as `caller' is deprecated and even throw an exception in strict of ES5). /ds
From: Thomas 'PointedEars' Lahn on 13 Jan 2010 10:50 Dmitry A. Soshnikov wrote: > Thomas 'PointedEars' Lahn wrote: >> Dmitry A. Soshnikov wrote: >> > Thomas 'PointedEars' Lahn wrote: >> >> Dmitry A. Soshnikov wrote: >> >> > David Mark wrote: >> >> >> > By the way, there's also one more ability to call overwritten >> >> >> > parent method just with `this._super()' expression. >> >> >> I assume you mean this._super.foo() to call the "super" foo >> >> >> method. >> >> > Actually, just this._super(), e.g. >> >> > >> >> > foo: function () { >> >> > this._super(); // will call `foo' in parent >> >> > } >> >> Never. Check your assumptions. >> > Please remember this ;) And your asking to show to you something that >> > you don't know. If you want, I can show you the code. >> Please do. I would be very much surprised if it worked as you posted. >> For that would require that the method was called as a method of itself. > > This is just a copy-paste of my theoretical thoughts based on well- > known patterns (with intermediate constructor to make prototype chain > and with wrappers for methods with the same name). > > Main goals of the code bellow: I don't think you were looking for the word "goals" here; perhaps "problems". > * No optimization; OK. > * No whatever; Pardon? > * scope chain of wrapped methods and wrapper will have some garbage; > * I *don't* use this pattern (and have never used) in production, this > is *just academical interest*; > * I don't like this pattern, it's just to show alternative. Not a viable or remotely equivalent alternative, though. > File for constructors ("classes") building, you can call it Class.js > or whatever: > > --------------------------------- > > function Class(params) { > > function Klass() { > this.initialize.apply(this, arguments); > } Calling an `initialize' method instead of using a constructor is indicative of a lack of minimum clue. Last I checked, it was one of Prototype.js's major flaws. > if (params.__extends) { > var __inheritance = function () {}; > __inheritance.prototype = params.__extends.prototype; > Klass.prototype = new __inheritance(); We have already established here that it is potentially more efficient and reasonably safe to create the dummy constructor only once. > Klass.prototype.constructor = Klass; OK. > Klass.superClass = params.__extends; Those identifiers are questionable. > } > > !params.initialize && (params.initialize = Class.emptyFn); > Klass.prototype.__class__ = Klass; Do not define properties which names start and end with `__'; those should be reserved to built-in properties. At least four of them (__defineGetter__, __defineSetter__, __iterator__ and __proto__) are built into one implementation (JavaScript) already. And of course `__class__' is wrong in itself. > for (var method in params) if (params.hasOwnProperty(method)) { I am using a similar approach, but I have come to realize that iterating over an Array using numeric indexes is probably safer and more efficient. > if (method == '__extends') { > continue; > } > Klass.prototype[method] = params[method]; > if (params.__extends && typeof params.__extends.prototype[method] > == 'function') { > (function (methodName) { > var __originalMethod = params[methodName]; > var __superMethod = params.__extends.prototype[methodName]; > Klass.prototype[methodName] = function () { > var __previousSuper = this._super; > this._super = __superMethod; > var result = __originalMethod.apply(this, arguments); > this._super = __previousSuper; > return result; > }; > })(method); You can't be serious. Efficiency aside, this is not thread-safe, not even exception-safe. So even if we would be operating in an ECMAScript vacuum without DOMs this would not be acceptable. > } > } > > return Klass; > > } > > Class.emptyFn = function () {}; > > --------------------------------- > > So, nothing special, all of this you all know. Unfortunately. > [...] > But as I said, I don't like this implementation much as it's not so > useful from the performance. Performance is the least of its issues. This is even worse than what Jorge proposed. > Regarding to implementation with `caller' which also will let to use > just `this.super()', I haven't yet code, will write later if will be > needed (but can tell, that only difference will be in marking methods > to set their `name' property, which is used in Spidermonkey's > implementation. Using that ability we can call parent methods by name, > using `caller' from the `this._super()', quit easy and elegant, but > dangerous as `caller' is deprecated and even throw an exception in > strict of ES5). Please refrain from posting it, then. Nothing useful/sane can be learned there. PointedEars -- Prototype.js was written by people who don't know javascript for people who don't know javascript. People who don't know javascript are not the best source of advice on designing systems that use javascript. -- Richard Cornford, cljs, <f806at$ail$1$8300dec7(a)news.demon.co.uk>
From: Dmitry A. Soshnikov on 13 Jan 2010 11:01 On Jan 13, 4:50 pm, Thomas 'PointedEars' Lahn <PointedE...(a)web.de> wrote: [...] > > foo: function () { > > this._super(); // will call `foo' in parent > > } > > Never. Check your assumptions. > So? I was asking to remember this words. And showed you that it's possible (regardless the code itself). Is it really never? I'm waiting your agreement that it's possible. Your helper David is also welcome for that. /ds
From: Dmitry A. Soshnikov on 13 Jan 2010 11:04
On Jan 13, 6:50 pm, Thomas 'PointedEars' Lahn <PointedE...(a)web.de> wrote: > Dmitry A. Soshnikov wrote: > > Thomas 'PointedEars' Lahn wrote: > >> Dmitry A. Soshnikov wrote: > >> > Thomas 'PointedEars' Lahn wrote: > >> >> Dmitry A. Soshnikov wrote: > >> >> > David Mark wrote: > >> >> >> > By the way, there's also one more ability to call overwritten > >> >> >> > parent method just with `this._super()' expression. > >> >> >> I assume you mean this._super.foo() to call the "super" foo > >> >> >> method. > >> >> > Actually, just this._super(), e.g. > > >> >> > foo: function () { > >> >> > this._super(); // will call `foo' in parent > >> >> > } > >> >> Never. Check your assumptions. > >> > Please remember this ;) And your asking to show to you something that > >> > you don't know. If you want, I can show you the code. > >> Please do. I would be very much surprised if it worked as you posted. > >> For that would require that the method was called as a method of itself. > > > This is just a copy-paste of my theoretical thoughts based on well- > > known patterns (with intermediate constructor to make prototype chain > > and with wrappers for methods with the same name). > > > Main goals of the code bellow: > > I don't think you were looking for the word "goals" here; perhaps > "problems". > > > * No optimization; > > OK. > > > * No whatever; > > Pardon? > > > * scope chain of wrapped methods and wrapper will have some garbage; > > * I *don't* use this pattern (and have never used) in production, this > > is *just academical interest*; > > * I don't like this pattern, it's just to show alternative. > > Not a viable or remotely equivalent alternative, though. > > > File for constructors ("classes") building, you can call it Class.js > > or whatever: > > > --------------------------------- > > > function Class(params) { > > > function Klass() { > > this.initialize.apply(this, arguments); > > } > > Calling an `initialize' method instead of using a constructor is indicative > of a lack of minimum clue. Last I checked, it was one of Prototype.js's > major flaws. > > > if (params.__extends) { > > var __inheritance = function () {}; > > __inheritance.prototype = params.__extends.prototype; > > Klass.prototype = new __inheritance(); > > We have already established here that it is potentially more efficient and > reasonably safe to create the dummy constructor only once. > > > Klass.prototype.constructor = Klass; > > OK. > > > Klass.superClass = params.__extends; > > Those identifiers are questionable. > > > } > > > !params.initialize && (params.initialize = Class.emptyFn); > > Klass.prototype.__class__ = Klass; > > Do not define properties which names start and end with `__'; those should > be reserved to built-in properties. At least four of them > (__defineGetter__, __defineSetter__, __iterator__ and __proto__) are built > into one implementation (JavaScript) already. And of course `__class__' is > wrong in itself. > > > for (var method in params) if (params.hasOwnProperty(method)) { > > I am using a similar approach, but I have come to realize that iterating > over an Array using numeric indexes is probably safer and more efficient. > > > > > if (method == '__extends') { > > continue; > > } > > Klass.prototype[method] = params[method]; > > if (params.__extends && typeof params.__extends.prototype[method] > > == 'function') { > > (function (methodName) { > > var __originalMethod = params[methodName]; > > var __superMethod = params.__extends.prototype[methodName]; > > Klass.prototype[methodName] = function () { > > var __previousSuper = this._super; > > this._super = __superMethod; > > var result = __originalMethod.apply(this, arguments); > > this._super = __previousSuper; > > return result; > > }; > > })(method); > > You can't be serious. Efficiency aside, this is not thread-safe, not even > exception-safe. So even if we would be operating in an ECMAScript vacuum > without DOMs this would not be acceptable. > > > } > > } > > > return Klass; > > > } > > > Class.emptyFn = function () {}; > > > --------------------------------- > > > So, nothing special, all of this you all know. > > Unfortunately. > > > [...] > > But as I said, I don't like this implementation much as it's not so > > useful from the performance. > > Performance is the least of its issues. This is even worse than what Jorge > proposed. > > > Regarding to implementation with `caller' which also will let to use > > just `this.super()', I haven't yet code, will write later if will be > > needed (but can tell, that only difference will be in marking methods > > to set their `name' property, which is used in Spidermonkey's > > implementation. Using that ability we can call parent methods by name, > > using `caller' from the `this._super()', quit easy and elegant, but > > dangerous as `caller' is deprecated and even throw an exception in > > strict of ES5). > > Please refrain from posting it, then. Nothing useful/sane can be learned > there. > Ah, common ;) I was asking do not discuss the code itself but to concentrate on the main thing we were talking about - is possible to use `this._super()' with correct meaning (and behavior) or not? That's all. About implementation with caller, I guess you've understand the main principle and can do it yourself if will be needed. /ds |