Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #11956 > unrolled thread

onclick=function(){obj.meth()}

Started byPuzzled <scratching.head@example.com>
First post2012-02-20 14:02 -0500
Last post2012-02-21 11:14 -0800
Articles 20 on this page of 40 — 11 participants

Back to article view | Back to comp.lang.javascript


Contents

  onclick=function(){obj.meth()} Puzzled <scratching.head@example.com> - 2012-02-20 14:02 -0500
    Re: onclick=function(){obj.meth()} "Tom de Neef" <tdeneef@qolor.nl> - 2012-02-20 20:20 +0100
      Re: onclick=function(){obj.meth()} Jake Jarvis <pig_in_shoes@yahoo.com> - 2012-02-20 20:39 +0100
        Re: onclick=function(){obj.meth()} "Richard Cornford" <Richard@litotes.demon.co.uk> - 2012-02-21 00:34 +0000
          Re: onclick=function(){obj.meth()} Stefan Weiss <krewecherl@gmail.com> - 2012-02-21 02:13 +0100
            Re: onclick=function(){obj.meth()} Richard Cornford <Richard@litotes.demon.co.uk> - 2012-02-21 04:05 -0800
          Re: onclick=function(){obj.meth()} Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-02-21 12:47 +0100
            Re: onclick=function(){obj.meth()} John G Harris <john@nospam.demon.co.uk> - 2012-02-21 15:59 +0000
    Re: onclick=function(){obj.meth()} Stefan Weiss <krewecherl@gmail.com> - 2012-02-20 21:09 +0100
      Re: onclick=function(){obj.meth()} "Evertjan." <exjxw.hannivoort@interxnl.net> - 2012-02-20 20:29 +0000
        Re: onclick=function(){obj.meth()} Puzzled <scratching.head@example.com> - 2012-02-20 16:50 -0500
          Re: onclick=function(){obj.meth()} "Evertjan." <exjxw.hannivoort@interxnl.net> - 2012-02-21 11:33 +0000
      Re: onclick=function(){obj.meth()} Puzzled <scratching.head@example.com> - 2012-02-20 15:47 -0500
        Re: onclick=function(){obj.meth()} Jake Jarvis <pig_in_shoes@yahoo.com> - 2012-02-20 22:38 +0100
          Re: onclick=function(){obj.meth()} Puzzled <scratching.head@example.com> - 2012-02-20 17:12 -0500
        Re: onclick=function(){obj.meth()} Gene Wirchenko <genew@ocis.net> - 2012-02-20 14:04 -0800
          "The this value" (Was: onclick=function(){obj.meth()}) Stefan Weiss <krewecherl@gmail.com> - 2012-02-21 01:37 +0100
            Re: "The this value" (Was: onclick=function(){obj.meth()}) Gene Wirchenko <genew@ocis.net> - 2012-02-20 17:20 -0800
            Re: "The this value" (Was: onclick=function(){obj.meth()}) Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-02-21 13:44 +0100
              Re: "The this value" (Was: onclick=function(){obj.meth()}) Stefan Weiss <krewecherl@gmail.com> - 2012-02-21 22:31 +0100
                Re: "The this value" (Was: onclick=function(){obj.meth()}) Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-02-22 10:55 +0100
                  Re: "The this value" (Was: onclick=function(){obj.meth()}) John G Harris <john@nospam.demon.co.uk> - 2012-02-22 15:58 +0000
          Re: onclick=function(){obj.meth()} "Richard Cornford" <Richard@litotes.demon.co.uk> - 2012-02-21 01:30 +0000
        Re: onclick=function(){obj.meth()} Scott Sauyet <scott.sauyet@gmail.com> - 2012-02-20 13:43 -0800
        Re: onclick=function(){obj.meth()} Stefan Weiss <krewecherl@gmail.com> - 2012-02-20 23:17 +0100
          Re: onclick=function(){obj.meth()} Puzzled <scratching.head@example.com> - 2012-02-20 17:48 -0500
            Re: onclick=function(){obj.meth()} Stefan Weiss <krewecherl@gmail.com> - 2012-02-21 00:57 +0100
            Re: onclick=function(){obj.meth()} "Richard Cornford" <Richard@litotes.demon.co.uk> - 2012-02-21 01:03 +0000
              Re: onclick=function(){obj.meth()} Gene Wirchenko <genew@ocis.net> - 2012-02-20 19:05 -0800
                Re: onclick=function(){obj.meth()} Richard Cornford <Richard@litotes.demon.co.uk> - 2012-02-21 04:14 -0800
                  Re: onclick=function(){obj.meth()} Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-02-21 13:54 +0100
                  Re: onclick=function(){obj.meth()} Gene Wirchenko <genew@ocis.net> - 2012-02-21 10:17 -0800
                    Re: onclick=function(){obj.meth()} Scott Sauyet <scott.sauyet@gmail.com> - 2012-02-21 11:57 -0800
                      Re: onclick=function(){obj.meth()} Gene Wirchenko <genew@ocis.net> - 2012-02-21 13:39 -0800
                        Re: onclick=function(){obj.meth()} Scott Sauyet <scott.sauyet@gmail.com> - 2012-02-22 05:07 -0800
              Re: onclick=function(){obj.meth()} Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-02-21 12:58 +0100
          Re: onclick=function(){obj.meth()} "Richard Cornford" <Richard@litotes.demon.co.uk> - 2012-02-21 00:45 +0000
            Re: onclick=function(){obj.meth()} Stefan Weiss <krewecherl@gmail.com> - 2012-02-21 02:22 +0100
          Re: onclick=function(){obj.meth()} Puzzled <scratching.head@example.com> - 2012-02-21 08:12 -0500
            Re: onclick=function(){obj.meth()} Scott Sauyet <scott.sauyet@gmail.com> - 2012-02-21 11:14 -0800

Page 2 of 2 — ← Prev page 1 [2]


#12037 — Re: "The this value" (Was: onclick=function(){obj.meth()})

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2012-02-22 10:55 +0100
SubjectRe: "The this value" (Was: onclick=function(){obj.meth()})
Message-ID<1941603.aqSPkdTlGX@PointedEars.de>
In reply to#12006
Stefan Weiss wrote:

> On 2012-02-21 13:44, Thomas 'PointedEars' Lahn wrote:
>> Stefan Weiss wrote:
>>> I could be mistaken about the details, but I'm too lazy to look it up
>>> now (it's late, and the wine was good).
>> It would appear to be prudent if one, in good scientific tradition,
>> refrained from making claims that one is unable or unwilling to
>> substantiate.
> 
> Where do you think you are, the Royal Society? A simple correction would
> have been enough, but you chose to ignore four hints at uncertainty
> ("IIRC"; "could be mistaken"; didn't look it up; had wine) to
> pontificate about scientific tradition. Get a life.

I daresay you would not have corrected yourself later.  If I had not taken 
the time for a correction, and nobody else would have tested or corrected 
you, the false claim would still be there.  Making such claims is ultimately 
harmful, in particular for beginners, and should be avoided.

It is particularly illogical of you to make such a claim on the grounds of 
unwillingness ("lazy") or an unfit condition ("the wine was good").  For you 
can make *and* substantiate the claim *later* when you are willing and fit 
for an answer (no matter if the reasoning for the claim turns out to be 
correct or not).


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@news.demon.co.uk>

[toc] | [prev] | [next] | [standalone]


#12049 — Re: "The this value" (Was: onclick=function(){obj.meth()})

FromJohn G Harris <john@nospam.demon.co.uk>
Date2012-02-22 15:58 +0000
SubjectRe: "The this value" (Was: onclick=function(){obj.meth()})
Message-ID<LNY2P3D9CRRPFwf4@J.A830F0FF37FB96852AD08924D9443D28E23ED5CD>
In reply to#12037
On Wed, 22 Feb 2012 at 10:55:36, in comp.lang.javascript, Thomas
'PointedEars' Lahn wrote:

  <snip>
>I daresay you would not have corrected yourself later.  If I had not taken
>the time for a correction, and nobody else would have tested or corrected
>you, the false claim would still be there.  Making such claims is ultimately
>harmful, in particular for beginners, and should be avoided.
  <snip>

Here, here! That's why I so often correct unjustified statements.

  John
-- 
John Harris

[toc] | [prev] | [next] | [standalone]


#11981

From"Richard Cornford" <Richard@litotes.demon.co.uk>
Date2012-02-21 01:30 +0000
Message-ID<_pGdnRvGgLpebt_SnZ2dnUVZ8rqdnZ2d@giganews.com>
In reply to#11965
Gene Wirchenko wrote:
> On Mon, 20 Feb 2012 15:47:45 -0500, Puzzled
<snip>
>     For the on clause, I have a call to the function with whatever
> parameters I need.  Here is one control from my experimental page:
>          <input name="CliCode" id="Text" onfocus="this.select();"
> onblur="return FieldData['CliCode'].FIValidation(this);" size="3"
> maxlength="3">
<snip>

You may be interested to know (possibly even pleased) that this is the 
technique that I have always considered best to associate javascript 
object instances when dealing with defining intrinsic event attributes 
inside javascript string values that are later parsed into DOM elements. 
Not quite the way I would do it, but the same principle.

In the end mine tended to be along the lines of:-

function Constructor(){
    this.index = Constructor.instances.length;
    Constructor.instances[this.index] = this;
}

Constructor.instances = [];

Constructor.prototype.forOnclick = function(){
    ...
    return false;
};

Constructor.prototype.insertElement = function(div){
    div.innerHTML = '<a href"#" ' +
         'onclick="return Constructor.instances[' +
         this.index +
         '].forOnclick()'">XXXX<\/a>';
};

The constructor function would be expected to be global available so 
hanging the array of instances off the constructor function object makes 
the individual instances globally available (and so available to the 
intrinsic event hander code) without introducing any new names into the 
global namespace.

But that was mostly in the day of Netscape 4 when messing about with 
strings of HTML code was necessary to solve some types otherwise 
insurmountable limitations in the browsers (in a cross browser way). 
These days I would tend to use the DOM creation/manipulation methods as 
they are (sufficiently) universally supported and their use makes for 
more easily understood code.

>     Advanced readers: "the this object" is awkward.

And ambiguous. In javascript - this - is a keyword, and has a value that 
is determined at runtime by how any particular function is called. In ES 
3 that value is always an object, but not necessarily in ES5 'strict 
mode'.

> "this" with or
> without the quotes is confusing.  Is there a better way to
> refer to
> the this object in English text?

The optimum approach is disputed, but putting quotes round it is likely 
to be taken either as a quote or as a reference to a string literal 
value.

Richard. 

[toc] | [prev] | [next] | [standalone]


#11967

FromScott Sauyet <scott.sauyet@gmail.com>
Date2012-02-20 13:43 -0800
Message-ID<7f0afaa5-9763-4276-a763-7fa82d8a1d03@w19g2000vbe.googlegroups.com>
In reply to#11961
Puzzled wrote:
>  function row( i )
>  {
>      var proxy = this ;   // create a closure-alias for 'this'
>      var rec_s  = '<tr><td><a href="javascript:void(0);" '+
> 'id="foo'+i+'" '+
>          'onclick=function(){proxy.esr(i)}>'+i+'</a>'+
>         '</td></tr>';
>      return rec_s ;
>  }
>
> It's my understanding that to use a method as an esr, I've to
> create and use a proxy for 'this' in the event binding as here,
> and use an anon function so as to be able to pass arguments.  Is
> that not so?

I think you need to re-read Stefan's response.

An event handler stored as a DOM attribute like this:

    <element onclick='xyz' ... >

should contain only the body of the function, and not the function
declaration itself.  Thus, don't do

    <element onclick='function(){doSomething();}' ...>

but instead simply

    <element onclick='doSomething();' ...>

If you're attaching an event handler directly in JS code (not running
through the attribute, then you would assign an actual function
reference:

    var myElement = ...
    myElement.onclick = function() {doSomething();}

although there are many alternative ways of attaching such a handler.

  -- Scott

[toc] | [prev] | [next] | [standalone]


#11968

FromStefan Weiss <krewecherl@gmail.com>
Date2012-02-20 23:17 +0100
Message-ID<jhugq7$qkn$1@news.albasani.net>
In reply to#11961
On 2012-02-20 21:47, Puzzled wrote:
> What I supplied was the simplest form that gives the error.

Actually, Evertjan posted a very nice and short explanation of why the
error occurred.

>  function row( i )
>  {
>      var proxy = this ;   // create a closure-alias for 'this'
>      var rec_s  = '<tr><td><a href="javascript:void(0);" '+
> 'id="foo'+i+'" '+ 
>          'onclick=function(){proxy.esr(i)}>'+i+'</a>'+
>  	'</td></tr>';
>      return rec_s ;
>  }

1) This will still trigger the same syntax error
2) The onclick attribute value still isn't quoted
3) This time, the variable i will not get interpolated

To remove the syntax error, you should have used

    ... + 'onclick="proxy.esr(' + i + ')">' + i + '</a>' + ...

> It's my understanding that to use a method as an esr, I've to
> create and use a proxy for 'this' in the event binding as here,
> and use an anon function so as to be able to pass arguments.  Is
> that not so? 

Ah, now I see where this is coming from.

It doesn't work the way you wrote it. The words are all there, but I
don't think you know _why_ you're supposed to "create a proxy for this"
and "use an anon function".

When your inline onclick handler is activated, it will evaluate whatever
is written in - onclick="..." from a different scope than your row()
function*. This means that the |this| value from row() is no longer
available. And neither is your proxy variable, which goes out of scope
as soon as the row() function returns. There are no references to it
left, so it will just be garbage collected. Putting its name in a string
doesn't count as a reference.

(* the details of the scoping and context of inline event handlers are a
little tricky; I'll skip those for now)

If you want to stick with inline (HTML) event handlers, you need a way
to refer to your x object from the outside. If x is visible globally,
this may be as simple as

    ... + 'onclick="x.esr(' + i + ')">' + i + '</a>' + ...

The cleaner way would be to create the your table rows with DOM methods
instead of HTML, and use event handler properties:

---------------------------------------------------------------------------
<!DOCTYPE html>
<html>
<head>
    <title>Test</title>
</head>
<body>

<table id="argl"></table>

<script>

function MyObj () {

    this.table = document.getElementById("argl");

    this.esr = function (i) {
        alert("Row " + i + " was clicked.");
    }

    this.row = function (i) {
        var tr = document.createElement("tr"),
            td = document.createElement("td"),
            that = this;   // <---- here's your proxy for |this|

        td.appendChild(document.createTextNode("Row nr: " + i));
        td.onclick = function () {
            that.esr(i);   // <---- and here's where you use it
        };
        tr.id = "foo" + i;
        tr.appendChild(td);
        this.table.appendChild(tr);
    }

}

var x = new MyObj();
x.row(3);
x.row(5);

</script>

</body>
</html>

---------------------------------------------------------------------------

It will even work without a proxy for |this|, if bind() is available:

    this.row = function (i) {
        var tr = document.createElement("tr"),
            td = document.createElement("td");

        td.appendChild(document.createTextNode("Row nr: " + i));
        td.onclick = function () {
            this.esr(i);  // <--- no more proxy needed, |this| is bound
        }.bind(this);

        ....

Hope this gets you on the right track.

- stefan

[toc] | [prev] | [next] | [standalone]


#11969

FromPuzzled <scratching.head@example.com>
Date2012-02-20 17:48 -0500
Message-ID<g6i5k7dkde7q52cilanl1qqo2jtcdqjsl9@4ax.com>
In reply to#11968
On Mon, 20 Feb 2012 23:17:42 +0100,
Stefan Weiss <krewecherl@gmail.com> wrote:

>On 2012-02-20 21:47, Puzzled wrote:
>> What I supplied was the simplest form that gives the error.
>
>Actually, Evertjan posted a very nice and short explanation of why the
>error occurred.
>
>>  function row( i )
>>  {
>>      var proxy = this ;   // create a closure-alias for 'this'
>>      var rec_s  = '<tr><td><a href="javascript:void(0);" '+
>> 'id="foo'+i+'" '+ 
>>          'onclick=function(){proxy.esr(i)}>'+i+'</a>'+
>>  	'</td></tr>';
>>      return rec_s ;
>>  }
>
>1) This will still trigger the same syntax error
>2) The onclick attribute value still isn't quoted
>3) This time, the variable i will not get interpolated
>
>To remove the syntax error, you should have used
>
>    ... + 'onclick="proxy.esr(' + i + ')">' + i + '</a>' + ...
>
>> It's my understanding that to use a method as an esr, I've to
>> create and use a proxy for 'this' in the event binding as here,
>> and use an anon function so as to be able to pass arguments.  Is
>> that not so? 
>
>Ah, now I see where this is coming from.
>
>It doesn't work the way you wrote it. The words are all there, but I
>don't think you know _why_ you're supposed to "create a proxy for this"
>and "use an anon function".
>
>When your inline onclick handler is activated, it will evaluate whatever
>is written in - onclick="..." from a different scope than your row()
>function*. This means that the |this| value from row() is no longer
>available. And neither is your proxy variable, which goes out of scope
>as soon as the row() function returns. There are no references to it
>left, so it will just be garbage collected. Putting its name in a string
>doesn't count as a reference.
>
>(* the details of the scoping and context of inline event handlers are a
>little tricky; I'll skip those for now)
>
>If you want to stick with inline (HTML) event handlers, you need a way
>to refer to your x object from the outside. If x is visible globally,
>this may be as simple as
>
>    ... + 'onclick="x.esr(' + i + ')">' + i + '</a>' + ...
>
>The cleaner way would be to create the your table rows with DOM methods
>instead of HTML, and use event handler properties:
>
>---------------------------------------------------------------------------
><!DOCTYPE html>
><html>
><head>
>    <title>Test</title>
></head>
><body>
>
><table id="argl"></table>
>
><script>
>
>function MyObj () {
>
>    this.table = document.getElementById("argl");
>
>    this.esr = function (i) {
>        alert("Row " + i + " was clicked.");
>    }
>
>    this.row = function (i) {
>        var tr = document.createElement("tr"),
>            td = document.createElement("td"),
>            that = this;   // <---- here's your proxy for |this|
>
>        td.appendChild(document.createTextNode("Row nr: " + i));
>        td.onclick = function () {
>            that.esr(i);   // <---- and here's where you use it
>        };
>        tr.id = "foo" + i;
>        tr.appendChild(td);
>        this.table.appendChild(tr);
>    }
>
>}
>
>var x = new MyObj();
>x.row(3);
>x.row(5);
>
></script>
>
></body>
></html>
>
>---------------------------------------------------------------------------
>
>It will even work without a proxy for |this|, if bind() is available:
>
>    this.row = function (i) {
>        var tr = document.createElement("tr"),
>            td = document.createElement("td");
>
>        td.appendChild(document.createTextNode("Row nr: " + i));
>        td.onclick = function () {
>            this.esr(i);  // <--- no more proxy needed, |this| is bound
>        }.bind(this);
>
>        ....
>
>Hope this gets you on the right track.
>
>- stefan


I do appreciate your responses, and believe that there's still a
fair bit of confusion here (for which I'm sure I'm responsible).

This is what I'm trying to do:

onclick = "this.some_method_identifier( arg, arg )"

where 'this' is the instance's self-reference.

It shouldn't be hard to do -- the terp certainly knows that
'this' is a special case, and should be able to grasp that when I
use it in a binding, I want its current value bound.   That's the
whole point of oo after all -- to give a "free" reference to an
instance such that the same code can be used for all instances.

But apparently the terp doesn't dereference 'this' at that moment
or do any trickery to create the expected binding.  Instead it
evaluates 'this' at the time the esr is called, which doesn't
work.

Yet people do make it work, I suppose, in some way.  I thought
the proxy and the anon function were the required magic, be
evidently not so, so now I'm back where I started, neck deep in
confusion and ignorance.

[toc] | [prev] | [next] | [standalone]


#11972

FromStefan Weiss <krewecherl@gmail.com>
Date2012-02-21 00:57 +0100
Message-ID<jhuml0$5f7$1@news.albasani.net>
In reply to#11969
On 2012-02-20 23:48, Puzzled wrote:
> This is what I'm trying to do:
> 
> onclick = "this.some_method_identifier( arg, arg )"
> 
> where 'this' is the instance's self-reference.
> 
> It shouldn't be hard to do

You think so? I'd say it is impossible in your case. Inline event
handlers are not executed in the scope of your x object. When they get
activated, they set |this| to the element node they're attached to. You
would need some other way to get the proper context for the row() method
from the _outside_. The only way to do that is to make your x object
globally available.

This is (IMHO) the biggest drawback of inline event handlers. Another is
that you're mixing code and markup. That's why I suggested using DOM
methods.

(What I would actually do in your case is different again: I would set
_one_ handler for the table, and use it to delegate events to the right
methods. But before you attempt that, you should be a little more
comfortable with the DOM and its methods.)

> -- the terp certainly knows that
> 'this' is a special case, and should be able to grasp that when I
> use it in a binding, I want its current value bound.   That's the
> whole point of oo after all -- to give a "free" reference to an
> instance such that the same code can be used for all instances.

If you want to pass a reference, then you should do that. What you're
actually doing is placing an identifier (or keyword) inside a string for
later evaluation in a different scope. Unless that identifier is global,
this won't work.

(BTW, I'm assuming that "terp" is the interpreter?)

> But apparently the terp doesn't dereference 'this' at that moment
> or do any trickery to create the expected binding.  Instead it
> evaluates 'this' at the time the esr is called, which doesn't
> work.

The |this| value is indeed special. Its value always depends on how a
function is called, and it will not be inherited by nested functions
(hence the need for a proxy if you want to preserve it).

> Yet people do make it work, I suppose, in some way.  I thought
> the proxy and the anon function were the required magic, be
> evidently not so, so now I'm back where I started, neck deep in
> confusion and ignorance.

I've shown you one way to make it work, and it doesn't require any
magic. The example I've posted is self-contained, it will run as-is and
do what you describe. We're willing to help you with the confusion and
ignorance, but you need to be open for advice. The way you want to write
it cannot work. Read the example again and try to understand what's
going on. The DOM methods may seem overly verbose at first, but there
are lots of wrappers and libraries out there to make your life easier.
(Or more confusing, in the case of some libraries ;-)


- stefan

[toc] | [prev] | [next] | [standalone]


#11977

From"Richard Cornford" <Richard@litotes.demon.co.uk>
Date2012-02-21 01:03 +0000
Message-ID<ULWdnTA4SoXqcN_SnZ2dnUVZ8jWdnZ2d@giganews.com>
In reply to#11969
Puzzled wrote:> On Mon, 20 Feb 2012 23:17:42 +0100,
<snip>
>
> I do appreciate your responses, and believe that there's still
> a fair bit of confusion here (for which I'm sure I'm responsible).

Yes, saying things is as many words (as it takes) often avoids 
confusion.

> This is what I'm trying to do:
>
> onclick = "this.some_method_identifier( arg, arg )"

That is meaningless in javascript terms precisely because the value of 
the - this - keyword is not decided at this point.

> where 'this' is the instance's self-reference.
>
> It shouldn't be hard to do -- the terp certainly knows that
> 'this' is a special case,

Presumably you are using "terp" as an abbreviation for interpreter.

In javascript the value of the - this - keyword is (always and only) 
decided at runtime, so the interpreter cannot know what the value will 
be at the time of tokenising/parsing/compiling the code. Javascript's - 
this - values are determined by _how_ any particular function is called, 
and the javascript engine cannot tell how a function has been called 
until it has been called.

> and should be able to grasp that when I
> use it in a binding,

Presumably you are using "terp" as an abbreviation for interpreter.

In javascript the value of the - this - keyword is (always and only) 
decided at runtime, so the interpreter cannot know what the value will 
be at the time of tokenising/parsing/compiling the code. Javascript's - 
this - values are determined by _how_ any particular function is called, 
and the javascript engine cannot tell how a function has been called 
until it has been called.

> I want its current value bound.   That's the
> whole point of oo after all -- to give a "free" reference to an
> instance such that the same code can be used for all instances.
>
> But apparently the terp doesn't dereference 'this' at that moment
> or do any trickery to create the expected binding.  Instead it
> evaluates 'this' at the time the esr is called, which doesn't
> work.

Yes, that is how it works, and you use - this - to refer to any 
individual instance from code defined once for a 'Class definition' by 
calling the instance's methods in a way that provides the 'correct' - 
this - value.

> Yet people do make it work, I suppose, in some way.

Yes, and the two techniques that work have been covered in other posts 
in this thread (though not necessarily in their only/optimum forms).

>  I thought
> the proxy and the anon function were the required magic, be
> evidently not so, so now I'm back where I started, neck deep in
> confusion and ignorance.

Computer programming is about understand enough to take control, which 
is the antithesis of  'magic'.

Richard. 

[toc] | [prev] | [next] | [standalone]


#11982

FromGene Wirchenko <genew@ocis.net>
Date2012-02-20 19:05 -0800
Message-ID<hb26k79hm00soqq0ij8o0bkdcerknbhqp4@4ax.com>
In reply to#11977
On Tue, 21 Feb 2012 01:03:52 -0000, "Richard Cornford"
<Richard@litotes.demon.co.uk> wrote:

>Puzzled wrote:> On Mon, 20 Feb 2012 23:17:42 +0100,

[snip]

>> This is what I'm trying to do:
>>
>> onclick = "this.some_method_identifier( arg, arg )"
>
>That is meaningless in javascript terms precisely because the value of 
>the - this - keyword is not decided at this point.

     Huh?  Is it not going to be the control that the onclick is for?

[snip]

>Computer programming is about understand enough to take control, which 
>is the antithesis of  'magic'.

     Plenty of magic deals with taking control.
          "One ring to rule them all..."

Sincerely,

Gene Wirchenko

[toc] | [prev] | [next] | [standalone]


#11991

FromRichard Cornford <Richard@litotes.demon.co.uk>
Date2012-02-21 04:14 -0800
Message-ID<3b8b871f-22ad-4e04-b27e-c0342d295576@s9g2000yqj.googlegroups.com>
In reply to#11982
On Feb 21, 3:05 am, Gene Wirchenko wrote:
> On Tue, 21 Feb 2012 01:03:52 -0000, Richard Cornford wrote:
>> Puzzled wrote:
> [snip]
>
>>> This is what I'm trying to do:
>
>>> onclick = "this.some_method_identifier( arg, arg )"
>
>>That is meaningless in javascript terms precisely because the
>> value of the - this - keyword is not decided at this point.
>
>      Huh?  Is it not going to be the control that the onclick is for?

Not necessarily, it depends on how the function is call. In response
to user interaction the browsers will reliably call the function as a
method of the DOM element with which it is associated (thus arranging
that the value of the - this - keyword is that DOM element), but it is
possible (indeed trivial) to call that function in a way that will
give the - this - keyword any value you choose. In Javascript the
value of the - this - keyword is decided (always and only) by how a
function is called.

> [snip]
>
>> Computer programming is about understand enough to take control, which
>> is the antithesis of  'magic'.
>
>      Plenty of magic deals with taking control.
>           "One ring to rule them all..."

Citing fiction in order to make a point about magic actually makes my
point. Fiction is as relevant to reality (which is where computer
programming goes on) as poetry or religion.

Richard.

[toc] | [prev] | [next] | [standalone]


#11994

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2012-02-21 13:54 +0100
Message-ID<4160767.OKRth7XBi8@PointedEars.de>
In reply to#11991
Richard Cornford wrote:

> On Feb 21, 3:05 am, Gene Wirchenko wrote:
>> On Tue, 21 Feb 2012 01:03:52 -0000, Richard Cornford wrote:
>>> Puzzled wrote:
>> [snip]
>>>> This is what I'm trying to do:
>>>> onclick = "this.some_method_identifier( arg, arg )"
>>>That is meaningless in javascript terms precisely because the
>>> value of the - this - keyword is not decided at this point.
>>
>>      Huh?  Is it not going to be the control that the onclick is for?

It is.

> Not necessarily, it depends on how the function is call. In response
> to user interaction the browsers will reliably call the function as a
> method of the DOM element with which it is associated (thus arranging
> that the value of the - this - keyword is that DOM element), but it is
> possible (indeed trivial) to call that function in a way that will
> give the - this - keyword any value you choose. In Javascript the
> value of the - this - keyword is decided (always and only) by how a
> function is called.

I do not see your point, and it appears you are preaching to the choir.  If 
that is an event-handler attribute value, then the OP is correct.  The way 
the function named `some_method_identifier' is called is *there*, in the 
attribute value.  There is no ambiguity (host object issues aside) about the 
*initial* `this' value in the context of that method (if it is callable).

>> [snip]
>>
>>> Computer programming is about understand enough to take control, which
>>> is the antithesis of  'magic'.
>>
>>      Plenty of magic deals with taking control.
>>           "One ring to rule them all..."
> 
> Citing fiction in order to make a point about magic actually makes my
> point. Fiction is as relevant to reality (which is where computer
> programming goes on) as poetry or religion.

That depends on whether that fiction is pure fantasy or based on scientific 
thought.  Consider Star Trek (not the reboot), for example.  (It is not by 
pure coincidence that I have a smartphone powered by an operating system 
named *Android*.)


PointedEars
-- 
Sometimes, what you learn is wrong. If those wrong ideas are close to the 
root of the knowledge tree you build on a particular subject, pruning the 
bad branches can sometimes cause the whole tree to collapse.
  -- Mike Duffy in cljs, <news:Xns9FB6521286DB8invalidcom@94.75.214.39>

[toc] | [prev] | [next] | [standalone]


#12000

FromGene Wirchenko <genew@ocis.net>
Date2012-02-21 10:17 -0800
Message-ID<uqn7k7hohf24i5tb0q5ugum7d971cmjdmh@4ax.com>
In reply to#11991
On Tue, 21 Feb 2012 04:14:39 -0800 (PST), Richard Cornford
<Richard@litotes.demon.co.uk> wrote:

>On Feb 21, 3:05 am, Gene Wirchenko wrote:
>> On Tue, 21 Feb 2012 01:03:52 -0000, Richard Cornford wrote:
>>> Puzzled wrote:
>> [snip]
>>
>>>> This is what I'm trying to do:
>>
>>>> onclick = "this.some_method_identifier( arg, arg )"
>>
>>>That is meaningless in javascript terms precisely because the
>>> value of the - this - keyword is not decided at this point.
>>
>>      Huh?  Is it not going to be the control that the onclick is for?
>
>Not necessarily, it depends on how the function is call. In response

     Which was specified in the example above.  Is there any case in
JavaScript where the value for this used in an onclick is other than
the control of the onclick?

>to user interaction the browsers will reliably call the function as a
>method of the DOM element with which it is associated (thus arranging
>that the value of the - this - keyword is that DOM element), but it is
>possible (indeed trivial) to call that function in a way that will
>give the - this - keyword any value you choose. In Javascript the
>value of the - this - keyword is decided (always and only) by how a
>function is called.
>
>> [snip]
>>
>>> Computer programming is about understand enough to take control, which
>>> is the antithesis of  'magic'.
>>
>>      Plenty of magic deals with taking control.
>>           "One ring to rule them all..."
>
>Citing fiction in order to make a point about magic actually makes my
>point. Fiction is as relevant to reality (which is where computer
>programming goes on) as poetry or religion.

     *You* brought up magic.

Sincerely,

Gene Wirchenko

[toc] | [prev] | [next] | [standalone]


#12003

FromScott Sauyet <scott.sauyet@gmail.com>
Date2012-02-21 11:57 -0800
Message-ID<4f205483-cae2-475f-95e2-d825db1856bf@t30g2000vbx.googlegroups.com>
In reply to#12000
Gene Wirchenko wrote:
> Is there any case in JavaScript where the value for this used in
> an onclick is other than the control of the onclick?

Yes:

  <a id="droid" onclick="alert(this); return false;">Obi-Wan</a>

  document.getElementById("droid").onclick.call({
    toString: function() {
      return "This is not the link you are looking for";
    }
  });

  -- Scott

[toc] | [prev] | [next] | [standalone]


#12007

FromGene Wirchenko <genew@ocis.net>
Date2012-02-21 13:39 -0800
Message-ID<rk38k7h1r5pkg3i8dsbe1h9nefb8tlebnq@4ax.com>
In reply to#12003
On Tue, 21 Feb 2012 11:57:25 -0800 (PST), Scott Sauyet
<scott.sauyet@gmail.com> wrote:

>Gene Wirchenko wrote:
>> Is there any case in JavaScript where the value for this used in
>> an onclick is other than the control of the onclick?
>
>Yes:
>
>  <a id="droid" onclick="alert(this); return false;">Obi-Wan</a>
>
>  document.getElementById("droid").onclick.call({
>    toString: function() {
>      return "This is not the link you are looking for";
>    }
>  });

     I do not understand how that answers my question.  The only this
reference that I see is in the onclick, and would that not refer to
the anchor?

     If I understand the second bit correctly, you are changing the
behaviour of the onclick (I am not sure of this), but I do not see
that you are changing the this value.

Sincerely,

Gene Wirchenko

[toc] | [prev] | [next] | [standalone]


#12041

FromScott Sauyet <scott.sauyet@gmail.com>
Date2012-02-22 05:07 -0800
Message-ID<7876f745-921e-4843-a495-fc0f7f7d5461@gi10g2000vbb.googlegroups.com>
In reply to#12007
Gene Wirchenko wrote:
> Scott Sauyet wrote:
>> Gene Wirchenko wrote:
>>> Is there any case in JavaScript where the value for this used in
>>> an onclick is other than the control of the onclick?
>>
>>  <a id="droid" onclick="alert(this); return false;">Obi-Wan</a>
>
>>  document.getElementById("droid").onclick.call({
>>    toString: function() {
>>      return "This is not the link you are looking for";
>>    }
>>  });
>
>      I do not understand how that answers my question.  The only this
> reference that I see is in the onclick, and would that not refer to
> the anchor?

It would when you click the anchor.  The Javascript engine creates a
DOM click event and fires it in the context of the anchor element.
But that same function can be called in another manner as I was
attempting to demonstrate.

>      If I understand the second bit correctly, you are changing the
> behaviour of the onclick (I am not sure of this), but I do not see
> that you are changing the this value.

Breaking it down a little, we might do

    var anchor = document.getElementById("droid");

which I assume you recognize as selecting the element in the document
with the ID of "droid", and assigning the `anchor` reference that
value.

Then we fetch the onclick property of that element:

    var onclickFunction = anchor.onclick;

This property is a function, created at some point by the Javascript
engine out of the text "alert(this); return false;".  We now have a
free-standing reference to that function.

We construct an object with only a single property, `toString`, a
simple function:

    var myObj = {toString: function() {return "This is not ...";}};

Finally, we invoke the function using `call`, which accepts as the
first parameter the object to be used as `this`:

    onClickFunction.call(myObj);

(If you haven't seen `call` or its sibling, `apply`, you should
probably look them up [1, 2] as they are part of what gives Javascript
its expressive power.)

Stringing these all together without the intermediate variables, we
get back to the code above.  You can see this in action at

    <http://jsfiddle.net/CrossEye/AthGj/>

When you click the link, the system will alert the toString
representation of the link, which in most (all?) browsers is the link
target.  When you click the button, you run the code we've been
discussing, and it runs the same function, but with the object in
question being our little object, and alerts "This is not the link
you're looking for".

Javascript is a multi-paradigm language, but some of its best
features, IMHO, are its functional-programming ones.  The onclick
function that is a property of that link element is not simply a
method of that element.  It is a function that can be reused in many
contexts.

  -- Scott

[1] https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/call
[2] https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/apply

[toc] | [prev] | [next] | [standalone]


#11990

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2012-02-21 12:58 +0100
Message-ID<4147811.bbFqFoj25p@PointedEars.de>
In reply to#11977
Richard Cornford wrote:

> Puzzled wrote:> On Mon, 20 Feb 2012 23:17:42 +0100,
>> This is what I'm trying to do:
>>
>> onclick = "this.some_method_identifier( arg, arg )"
> 
> That is meaningless in javascript terms precisely because the value of
> the - this - keyword is not decided at this point.

Incorrect.  `this' in an event-handler *attribute* value is and always has 
been a reference to the DOM object representing the element having that 
attribute value.

However, issues arise if `some_method_identifier' is not a stand-in for a 
built-in method of that DOM object or an object in its prototype chain.  A 
DOM object is a host object, and per the ECMAScript Language Specification 
the algorithms of the Specification, including the `[[Put]]' and `[[Get]]' 
algorithms to set and retrieve property values, respectively, do not need to 
be implemented as specified.  IOW:

  With host objects, all bets are off.
    -- (attributed to) Lasse Reichstein Nielsen
 
>> and should be able to grasp that when I use it in a binding,
> 
> Presumably you are using "terp" as an abbreviation for interpreter.
> 
> In javascript the value of the - this - keyword is (always and only)
> decided at runtime, 

Which is precisely why the followed approach may work, given the right 
method call. 

> so the interpreter cannot know what the value will be at the time of
> tokenising/parsing/compiling the code.

It does not have to in this case.

>> I thought the proxy and the anon function were the required magic, be
>> evidently not so, so now I'm back where I started, neck deep in
>> confusion and ignorance.
> 
> Computer programming is about understand enough to take control, which
> is the antithesis of  'magic'.

ACK.


PointedEars
-- 
Anyone who slaps a 'this page is best viewed with Browser X' label on
a Web page appears to be yearning for the bad old days, before the Web,
when you had very little chance of reading a document written on another
computer, another word processor, or another network. -- Tim Berners-Lee

[toc] | [prev] | [next] | [standalone]


#11976

From"Richard Cornford" <Richard@litotes.demon.co.uk>
Date2012-02-21 00:45 +0000
Message-ID<CJqdnV4mB4avdN_SnZ2dnUVZ8lGdnZ2d@giganews.com>
In reply to#11968
Stefan Weiss wrote:
> On 2012-02-20 21:47, Puzzled wrote:
>> What I supplied was the simplest form that gives the error.
>
> Actually, Evertjan posted a very nice and short explanation
> of why the error occurred.
>
>>  function row( i )
>>  {
>>      var proxy = this ;   // create a closure-alias for 'this'
>>      var rec_s  = '<tr><td><a href="javascript:void(0);" '+
>> 'id="foo'+i+'" '+
>>          'onclick=function(){proxy.esr(i)}>'+i+'</a>'+
>>  '</td></tr>';
>>      return rec_s ;
>>  }
>
> 1) This will still trigger the same syntax error
> 2) The onclick attribute value still isn't quoted
> 3) This time, the variable i will not get interpolated
>
> To remove the syntax error, you should have used
>
>    ... + 'onclick="proxy.esr(' + i + ')">' + i + '</a>' + ...
>
>> It's my understanding that to use a method as an esr, I've to
>> create and use a proxy for 'this' in the event binding as
>> here, and use an anon function so as to be able to pass
>> arguments.  Is that not so?
>
> Ah, now I see where this is coming from.
>
> It doesn't work the way you wrote it. The words are all there,
> but I don't think you know _why_ you're supposed to "create a
> proxy for this" and "use an anon function".
>
> When your inline onclick handler is activated, it will evaluate
> whatever is written in - onclick="..."
<snip>

No, not at that point. The syntax error will manifest itself when the 
string value defined in the function above is used to create DOM 
elements (when it is parsed).  If there was no syntax error in the 
ONCLICK attribute in the HTML it would be possible, after the string of 
HTML text has been parsed to create part of the DOM, to find that 
element in the DOM, examine its - onclick - property and see that its 
value is a function object and, by converting that object to a string, 
examine the code it contains, prior to any user interaction. This would 
only be possible if the onclick property's function were created prior 
to any possible user interaction with the element in the DOM.

Richard. 

[toc] | [prev] | [next] | [standalone]


#11980

FromStefan Weiss <krewecherl@gmail.com>
Date2012-02-21 02:22 +0100
Message-ID<jhurkq$3h5$1@news.albasani.net>
In reply to#11976
On 2012-02-21 01:45, Richard Cornford wrote:
> Stefan Weiss wrote:
>> When your inline onclick handler is activated, it will evaluate
>> whatever is written in - onclick="..."
> <snip>
> 
> No, not at that point. The syntax error will manifest itself when the 
> string value defined in the function above is used to create DOM 
> elements (when it is parsed).

Our posts overlapped, please see my other reply in this thread. This
seems to be particular to Internet Explorer.

> If there was no syntax error in the 
> ONCLICK attribute in the HTML it would be possible, after the string of 
> HTML text has been parsed to create part of the DOM, to find that 
> element in the DOM, examine its - onclick - property and see that its 
> value is a function object and, by converting that object to a string, 
> examine the code it contains, prior to any user interaction. This would 
> only be possible if the onclick property's function were created prior 
> to any possible user interaction with the element in the DOM.

In browsers other than IE(8?), no syntax error will be triggered until
the user clicks - OR until a script tries to access the value of
ele.onclick. This last part was news for me, too. Thanks.


- stefan

[toc] | [prev] | [next] | [standalone]


#11995

FromPuzzled <scratching.head@example.com>
Date2012-02-21 08:12 -0500
Message-ID<7r27k75mlb1iod7r1i0iu9vb4c2m6jbe1l@4ax.com>
In reply to#11968
On Mon, 20 Feb 2012 23:17:42 +0100,
Stefan Weiss <krewecherl@gmail.com> wrote:

>Hope this gets you on the right track.

It did, and *many* thanks for that.  

At first I resisted accepting what you were obliquely telling me
because I found it too hideous to contemplate.  But after downing
a pint of whisky (no, not really) I relaxed enough to think about
it.  It's still eye-wateringly hideous, but I've always been able
to accept reality when I've no other choice.

To me, the key concepts here are

a) js is at best pseudo-oo because it doesn't maintain under all
circumstances the defining oo relationship:  that of the object
instance to its properties.

b) a within-element event "binding" remains, at least in effect,
nothing but a string until source-interpreted (eeeuw, shades of
lisp and apl) during the lookup process that determines who
should service the current event.  It's that choice --to delay
the binding until the object relationship has been lost-- that
makes js a pseudo-oo language.

So, the solution (in my case at least) is to maintain within each
instance the name of the instance and substitute it as the
self-ref for within-element bindings, e.g.

var foo = constr('foo'...
function constr( selfid,...)
{ this.InstName = selfid ; this.click_esr = cesr ; }
function cesr( j ) {...}

<a .... onclick="'+this.InstName+'.click_esr('+i+...');">'+... 



Thanks to everyone who tried to explain to me the full
horribleness of what's going on. 

[toc] | [prev] | [next] | [standalone]


#12002

FromScott Sauyet <scott.sauyet@gmail.com>
Date2012-02-21 11:14 -0800
Message-ID<ab5259e5-a670-48f2-afd3-31038cf5f75d@w4g2000vbc.googlegroups.com>
In reply to#11995
Puzzled wrote:
> Stefan Weiss wrote:
>> Hope this gets you on the right track.
>
> It did, and *many* thanks for that.
>
> At first I resisted accepting what you were obliquely telling me
> because I found it too hideous to contemplate.  But after downing
> a pint of whisky (no, not really) I relaxed enough to think about
> it.  It's still eye-wateringly hideous, but I've always been able
> to accept reality when I've no other choice.

I still say that this is the only good time to accept reality!  Don't
do so if you have any choice.

> To me, the key concepts here are
>
> a) js is at best pseudo-oo because it doesn't maintain under all
> circumstances the defining oo relationship:  that of the object
> instance to its properties.

Javascript can certainly be used as an OO language.  The fact that it
uses prototypal rather than classical inheritance is the main
difference between it and more mainstream OO languages.

But it is not an OO-only language in the way that, say, Java or C# are
OO languages.  I often use it more as a functional language.

I think what you're reacting to is the fact that functions are first-
class objects.  Although they can be used as object methods, they are
not simply object methods.  I'm afraid you won't get much support here
that this is horrible.  I imagine many other regulars would agree with
me that this is one of the best features of the language.


> b) a within-element event "binding" remains, at least in effect,
> nothing but a string until source-interpreted  ...

When you say "within-element", you are confusing two different
languages.  Javascript can be embedded within HTML, and that is in
essence what you're doing with code like this.  There are various ways
to bind event handlers to document nodes.  When you do it in markup
like this, you have to live with the restriction that markup is just
text to be interpreted.  There are many alternatives.  One is
demonstrated at

    <http://jsfiddle.net/CrossEye/wxQ2K/>

(I didn't understand your requirements well enough to try to use your
terminology, but this should show the ideas.)

>(eeeuw, shades of  lisp and apl)

Yahoo, shades of SCHEME and LISP!  :-)

> ... during the lookup process that determines who
> should service the current event.  It's that choice --to delay
> the binding until the object relationship has been lost-- that
> makes js a pseudo-oo language.

Again, this seems to be a confusion between the JS and the HTML.  You
are creating some HTML representing elements to be added to the
document.  Your Javascript has been left behind at this point.


> So, the solution (in my case at least) is to maintain within each
> instance the name of the instance and substitute it as the
> self-ref for within-element bindings, e.g.
>
> var foo = constr('foo'...
> function constr( selfid,...)
> { this.InstName = selfid ; this.click_esr = cesr ; }
> function cesr( j ) {...}
>
> <a .... onclick="'+this.InstName+'.click_esr('+i+...');">'+...

That's one way, but there are so many alternatives.  If you're
generating the elements within code (rather than generating markup
that the HTML engine must interpret to make elements) then there are
much more elegant techniques.


> Thanks to everyone who tried to explain to me the full
> horribleness of what's going on.

You may find that Javascript is not to your liking, but you're not
likely to get too much sympathy in comp.lang.javascript for the notion
that the language is horrible.  ;-)

  -- Scott

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

Back to top | Article view | comp.lang.javascript


csiph-web