Prev: FAQ Topic - Why does simple decimal arithmetic give strange results? (2010-03-31)
Next: Consolidate Credit Card Debt
From: Richard Cornford on 1 Apr 2010 07:31 On Apr 1, 12:06 pm, nick wrote: > What about arguments.callee? That's good enough for > returning a reference to the same function. arguments.callee is good enough for (anonymously) returning a reference to the current function. It won't be available in ES5 strict mode, and it has been observed that some implementations are optimized such that they don't create an - arguments - object if you don't refer to it, so using - arguements.callee - will prevent that. <snip> > this.register = function (key, onPress, onRelease) { > if (!initted) init(); > if (!onPress && !onRelease) me.unregister(key); > callbacks[toCharCode(key)] = [onPress, onRelease]; > return arguments.caller; > } <snip> Apparently one issue with using - arguments.callee - is typeing it wrongy and ending up with - argrument.caller -. ;-) Richard.
From: nick on 1 Apr 2010 07:43 On Apr 1, 7:31 am, Richard Cornford <Rich...(a)litotes.demon.co.uk> wrote: > On Apr 1, 12:06 pm, nick wrote: > > > What about arguments.callee? That's good enough for > > returning a reference to the same function. > > arguments.callee is good enough for (anonymously) returning a > reference to the current function. It won't be available in ES5 strict > mode, and it has been observed that some implementations are optimized > such that they don't create an - arguments - object if you don't refer > to it, so using - arguements.callee - will prevent that. > > <snip>> this.register = function (key, onPress, onRelease) { > > if (!initted) init(); > > if (!onPress && !onRelease) me.unregister(key); > > callbacks[toCharCode(key)] = [onPress, onRelease]; > > return arguments.caller; > > } > > <snip> > > Apparently one issue with using - arguments.callee - is typeing it > wrongy and ending up with - argrument.caller -. ;-) > > Richard. hahahah... apparently so. My "real" code actually returns me.register, with 'me' being the 'this' that's getting created by my new function(). I guess it is kind of a deviant pattern, but WTH. Anyway, thanks for your help :) Here's the script as it is now if anyone is interested. // global app object window.myApp = window.myApp || {}; // our key handling module myApp.keys = myApp.keys || new function(){ var me=this, down=0, up=1, initted, callbacks={}; // public methods me.register = function (key, onPress, onRelease) { if (!initted) init(); if (!onPress && !onRelease) me.unregister(key); callbacks[toCharCode(key)] = [onPress, onRelease]; return me.register; } me.unregister = function (key) { delete callbacks[key]; return me.unregister; } me.list = function (key) { return key ? callbacks[key] : callbacks; }; me.clear = function () { callbacks = {}; return me; } // private methods function init(){ initted = true; document.onkeydown = function(evt){ return on(evt, down) } document.onkeyup = function(evt){ return on(evt, up) } } function on(evt, fn) { evt = evt || window.event; //IE reports window.event var cb = callbacks[evt.chrCode || evt.keyCode]; if (cb && typeof cb[fn] == 'function') return cb[fn](evt); return true; } function toCharCode(v){ return v === +v ? v : (v+'_').toUpperCase().charCodeAt(0); } }
From: Richard Cornford on 1 Apr 2010 08:02 On Mar 31, 11:01 pm, nick wrote: > On Mar 31, 7:15 am, Richard Cornford wrote: >> On Mar 31, 3:41 am, nick wrote: > So, I was using the good old module pattern, and I had >>> ... >>> const down = 0, up = 1, callbacks = {}; > >> ^^^^^ >> So this is JavaScript(tm) only, not a (cross or multi) >> browser script? > > Yeah, the thing I'm working on is eventually going to be > a firefox / chrome extension, although now that you mention > it I probably need to get rid of const in case I do a > bookmarklet version and for the sake of ES compliance. As they are going to be tucked away in a closure anyway the difference between their being constants and so not being changeable and their being inaccessible variable is probably minimal. External code that went to the effort of rendering the variable changed could as easily modify the constants, so you only really need to remind yourself that they are not supposed to be changed, which is usually done with the naming convention of using all upper case (and underline) names for variables that represent constants. >> I always think that code in a function body after a - return - >> statement is needlessly obscure/confusing. Personally, I >> prefer function code to be structured such that it reflects >> how it will be handled; to reflect the two phase - variable >> instantiation then code execution handling, so with the >> variable and inner function declarations at the top. > > I see your point. To me, the return statement serves as a > reminder that there is no 'loose' code after that point, > only function declarations. So the var declarations, > public properties and any other init code goes before the > return, and private functions go after. I suppose this is > a matter of taste. It is not to my taste, but not worth too much argument. I do wonder what happens when the function has no return statement but still have internal function declarations. Having an implied return at the end of a function body makes sense (what else would happen there), but having it somewhere before the end seems non-obvious. Perhaps that suggests no function bodies without explicit return statements, even if they don't always return expressions (even if that would be counter to any effort to reduce typing). <snip> >> No, it has even been (inappropriately) employed in one or >> two general purpose javascript libraries. > > Inappropriately because the object created by calling 'new' was > discarded without being used, or for some other reason? Yes, that was the substance of the criticism, and no counter argument was proposed by the authors in question. In general, if you have to otherwise indistinguishable alternatives the one that creates the superfluous object becomes the inferior option. <snip> >>> but it sure looks a lot neater. > >> I don't see much in it, though I would prefer to see the - new - >> operator only used in conjunction with references to functions that >> are designed as constructors for (possibly) multiple instances of a >> type of object. > > Well, I say it looks cleaner because there are less 'weird symbols' > laying around, But more keywords. > and because the closure doesn't need to return > anything... it looks more like 'most constructs' in other > languages, and less 'javascripty.' I don't know about looking like constructs in other languages. Using - new - in, for example, Java has a meaning that would be difficult to translate into this proposed use. Also, the - (function(){ ... })(); - construct was hardly used prior to 2003 (and then not for encapsulation/privacy purposes), and so javascript is more then twice the age of (the general use of) that construct, which makes it questionable to call it "javascripty". > But, as you pointed out, this is all just a > matter of taste. <snip> Largely, yes, but not necessarily entirely. Richard.
From: Asen Bozhilov on 1 Apr 2010 08:09 nick wrote: > My "real" code actually returns me.register, with 'me' being the > 'this' that's getting created by my new function(). I guess it is kind > of a deviant pattern, but WTH. Anyway, thanks for your help :) > > Here's the script as it is now if anyone is interested. > [...] var me=this; me.register = function(){}; Why do you use that code? `this` associated with execution context immutable, and will be much more fast if you use `this` instead of identifier, which evaluate against Scope Chain. I always wonder, what is the reason for people want "private" emulation in Javascript. If the developer, who use your code is unreasonable person, you cannot stop errors and mistakes. I prefer to use naming convention for private properties. For example: this._privateMethod = function() { //... }; It's enough, before language support native access modifiers.
From: johnwlockwood on 1 Apr 2010 10:56
On Apr 1, 7:09 am, Asen Bozhilov <asen.bozhi...(a)gmail.com> wrote: <snip> > var me=this; > me.register = function(){}; Isn't this done so you can reference the this from a closure function? like: function MyObject(id) { var me = this; me.id = id; me.getId_ = function() { return me.getId(); }; }; var MyObject.prototype.getId = function() { var me = this; return me.id; } var myObject = MyObject("test"); var getMyObjectId = myObject.getId_; // or assign myObject.getId_ as a callback alert(getMyOjbectId()); // alert should display "test" > > Why do you use that code? `this` associated with execution context > immutable, and will be much more fast if you use `this` instead of > identifier, which evaluate against Scope Chain. I was told there was a bug in one of the browsers that caused a problem if you didn't use the me=this. If that is not true, I could do it like so: function MyObject(id) { this.id = id; this.getId_ = function() { return this.getId(); }; }; var MyObject.prototype.getId = function() { return this.id; } This is obviously a very contrived example. -John |