From: Richard Cornford on
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
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
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
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
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