Restricting A Function To Be In Scope of Constructor Method

P

Patient Guy

The code below shows the familiar way of restricting a function to be a
method of a constructed object:

function aConstructor(arg)
{
if (typeof(arg) == "undefined")
return (null);
this.property1 = arg;
this.property2 = aConstantDefinedGlobally;
this.method1 = function (anArg) {
return (this.property1 + this.property2);
};
this.method2 = function (arg1, arg2) {
var aVar = arg1 + this.property1;
// a lot---maybe 100 lines of method code
// .
// .
// .
// .
};
return (this);
}

Method 'method1' and the code manipulating object properties was added to
make it a better example in showing brief bits of code.

Note that method 'method2' is rather long in terms of lines of code.

Suppose for the sake of code readability, the attempt is made to define
the method "external" to the constructor, but that it still be a method of
the object, and not a function in global scope (oh, and another question:
is a function actually a method of the global object?). As so:

function method2(arg1, arg2)
{
var aVar.arg1 + this.property1;
// lots of lines of code follows
}

function aConstructor(arg)
{
if (typeof(arg) == "undefined")
return (null);
this.property1 = arg;
this.property2 = aConstantDefinedGlobally;
this.method1 = function (anArg) {
return (this.property1 + this.property2);
};
this.method2 = method2;
return (this);
}

Of course, this was tried and does not work, with the 'this' object is
function method2 is the global object.

So the question is, how can I set up the code so that method 'method2'
remains a method of the constructor and should not be called as a function
in global scope?
 
R

Richard Cornford

Patient Guy wrote:
function method2(arg1, arg2)
{
var aVar.arg1 + this.property1;
// lots of lines of code follows
}

function aConstructor(arg)
{
if (typeof(arg) == "undefined")
return (null);

There is no point in doing this in a constructor as a NewExpression
cannot evaluate as a primitive value (including Null). If you try to
return a primitive value from a constructor the result will still be the
object constructed.
this.property1 = arg;
this.property2 = aConstantDefinedGlobally;
this.method1 = function (anArg) {
return (this.property1 + this.property2);
};
this.method2 = method2;
return (this);

There is no point in explicitly returning - this -.

Given the code you show the optimum definition would be:-

function aConstructor(arg){
this.property1 = arg;
}

aConstructor.prototype.method1 = function (anArg) {
return (this.property1 + this.property2);
};

aConstructor.prototype.method2 = function(arg1, arg2){
var aVar.arg1 + this.property1;
// lots of lines of code follows
};

aConstructor.prototype.property2 = aConstantDefinedGlobally;

(with the considerable advantage that the function objects that
represent the methods are only created once and their assignments is
also only made once).
Of course, this was tried and does not work, with the 'this'
object is function method2 is the global object.

In javascript the - this - value is always, and only, determined by how
a function is called. You have not shown any code that instantiates
objects or calls methods of those objects so your assertions about the -
this -value - are no more than assertions.
So the question is, how can I set up the code so that method
'method2' remains a method of the constructor

There is no indication in your posted code than you have any actual
desire to create methods of the constructor.
and should not be called as a
function in global scope?

You are in control of how you call your code.

Richard.
 
P

Patient Guy

Patient Guy wrote:


There is no point in doing this in a constructor as a NewExpression
cannot evaluate as a primitive value (including Null). If you try to
return a primitive value from a constructor the result will still be the
object constructed.

Yes, I have seen this. Probably a more careful reading of the
specification will tell me that when no object is to be instantiated, it
is better to return nothing?

There is no point in explicitly returning - this -.

Okay.



Given the code you show the optimum definition would be:-

function aConstructor(arg){
this.property1 = arg;
}

aConstructor.prototype.method1 = function (anArg) {
return (this.property1 + this.property2);
};

aConstructor.prototype.method2 = function(arg1, arg2){
var aVar.arg1 + this.property1;
// lots of lines of code follows
};

aConstructor.prototype.property2 = aConstantDefinedGlobally;

(with the considerable advantage that the function objects that
represent the methods are only created once and their assignments is
also only made once).



This is probably what I am looking for and will test. How well is this
implemented in different environments (browsers) claiming to run
Javascript?


In javascript the - this - value is always, and only, determined by how
a function is called. You have not shown any code that instantiates
objects or calls methods of those objects so your assertions about the -
this -value - are no more than assertions.


You can see that within the first example of the constructor function I
defined as a method an "external" function (a function in global scope),
or by "external," a function outside the scope of the constructor
function. It was my intention that by defining the external function as a
method of the constructor, that the function would inherit the object
being constructed as 'this,' but this was clearly not the case.

With C++ of course, there is the notation

class::method

which can be used for privileged method definition outside the class
definition. I was just trying to find the Javascript alternative if there
was one.

There is no indication in your posted code than you have any actual
desire to create methods of the constructor.

The first example of the constructor function I gave showed coding that
defined methods to the constructor in which the code was within the
constructor (function) definition.

The example that followed was an explanation of my attempt to define
methods outside the constructor function definition (beyond its braces
'{}') and also restrict the function definition as being a method of the
constructor. I just was unable to find the correct coding for making that
restriction.
 
R

Richard Cornford

Patient said:
Yes, I have seen this. Probably a more careful reading of
the specification will tell me that when no object is to be
instantiated, it is better to return nothing?

NewExpression cannot evaluate as a primitive value (including
Undefined).

This is probably what I am looking for and will test.

It probably is not, but it is how the code you posted should have been
written.
How well is this implemented in different environments
(browsers) claiming to run Javascript?

Most browsers that claim to run javascript actually do run javascript.
You can see that within the first example of the constructor
function I defined as a method an "external" function (a
function in global scope), or by "external," a function
outside the scope of the constructor function.

The context in which a function is declared (or function expression
evaluated) influences its scope chain.
It was my intention that by defining the
external function as a method of the constructor,

"Defining the external function as a method of the constructor" is
meaningless. You never assigned any functions as methods of the
constructor.
that the function would inherit the object being
constructed as 'this,' but this was clearly not the case.

In javascript the - this - value in a function is determined always, and
only, by how a function is called (or a per-call basis).
With C++ of course, there is ...

C++ is not javascript (not even very like javascript).

The first example of the constructor function I gave showed
coding that defined methods to the constructor

"Defined methods to the constructor" is more meaningless than the last
formulation. There is no indication in your posted code than you have
any actual desire to create methods of the constructor.
in which the code was within
the constructor (function) definition.

The example that followed was an explanation of my attempt to
define methods outside the constructor function definition
(beyond its braces '{}') and also restrict the function
definition as being a method of the constructor.

Apart from the whole "method of the constructor" thing being an apparent
misconception of what a method of an object is, there is nothing in your
post to suggest what it is you are trying to do, just different ways of
failing to do whatever it is.
I just was unable to find the correct coding for making
that restriction.

Pinning down why you want to make "that restriction" is probably the
quickest approach to finding out what you need to know.
<snip>

Richard.
 
R

RobG

Patient Guy wrote:
[...]
You can see that within the first example of the constructor function I
defined as a method an "external" function (a function in global scope),
or by "external," a function outside the scope of the constructor
function. It was my intention that by defining the external function as a
method of the constructor, that the function would inherit the object
being constructed as 'this,' but this was clearly not the case.

As Richard said, the value of the this operator is established by how
the function is called. It always refers to the object that the
function is a method of, so if you want a function's this operator to
point to a particular object, you have to add a property to the object
that references the function, then use it to call the function:

function FuncA (){
this.name = 'functionA';
}

function funcB(){
alert(this.name);
}

var blah = new FuncA();
blah.funcB = funcB;
blah.funcB(); // Shows 'functionA'


The call method is another option:

funcB.call(blah); // Shows 'functionA'


[...]
The example that followed was an explanation of my attempt to define
methods outside the constructor function definition (beyond its braces
'{}') and also restrict the function definition as being a method of the
constructor. I just was unable to find the correct coding for making that
restriction.

Then why not just declare it as a property of the function or (more
efficiently) as a property of its prototype:

function FuncA (){
this.name = 'functionA';
}

FuncA.prototype.funcB = function(){
alert(this.name);
}

var blah = new FuncA();
blah.funcB(); // Shows 'functionA'


If you mean declared and added from outside the function's scope (it
may not be global, it could be within the scope of some other function)
and not available at all to other functions, then I think it's not
possible. So called "private" methods can only be added from within
the function's own scope - otherwise, they wouldn't be characterised as
"private".
 
V

VK

Patient said:
So the question is, how can I set up the code so that method 'method2'
remains a method of the constructor and should not be called as a function
in global scope?

A brief answer:
You can't do it in JavaScript because of a specification bug (because
of well-thought engine mechanics, because of bad implementations of
totally right specifications, because of ... - you really choose the
best from the list or fill your own one: do not start yet another
discussions :)

Because of this ... phenomenon an external (declared in the Global
scope) function is just an external function no fricking matter what,
even if you made it to be a member of a custom object.
(ECMA specs are telling the same in much more details and by using many
savvy words, but the above sentence really contains all info you really
need to get the idea).



A medium-length answer:
External functions know nothing about custom objects they appertain to
and there is no way to educate them by the conventional ways. But:

a) Unless you are using JScript.NET or planning to use your script in
JScript.NET later: you can augment the function object to hold some
extra info. (JScript.NET if compiled or/and run in quick mode doesn't
allow function augmentation and it will break with error).

b) Functions do not know if and what custom objects do they appertain
to, but they can point *sometimes* to the object-caller over
arguments.caller property. Unfortunately there were security issues
with this property and it is not consistent across modern browsers. It
is either removed all together or partially blocked. It also says
"null" most of the time, and most of the time it says it at the time
when you'd like to hear something completely else :)

By choosing or by combining both ways And by accepting more narrow set
of supported environments you can emulate in external functions (with
an acceptable level of "trust-wordiness"):


1) Static protected method of a singleton:

<script>
function method1() {
// a lot of code
// and finally:
if (method1.owner) {
window.alert(method1.owner.name);
}
}

function myConstructor() {
if (myConstructor.$instance) {
return myConstructor.$instance;
}
else {
myConstructor.$instance = this;
this.name = 'myObject';
this.method1 = method1;
this.method1.owner = this;
}
}

var obj = new myConstructor();
obj.method1();
</script>


2) Static protected method constructor of a class constructor. That was
I guess what you called "in the scope of constructor method"

<script>
function method1() {
window.alert('The Glory and the mISERY of JavaScript...');
}
method1.toString = function() {
if ((arguments.caller)
&&(arguments.caller === myConstructor)) {
return method1;
}
else {
return window.alert('Error');
}
}

function myConstructor() {
this.method1 = method1;
}

var obj = new myConstructor();
obj.method1();
method1();
</script>

You noticed of course that this method is still only "half-protected".
It will refuse to participate in any constructions unless they led by
myConstructor. You may add to the last check
.... ||(myConstructor.isPrototypeOf(arguments.caller))
to allow not only myConstructor but also its derivates, but it gets a
bit shaky.

At the same time it still can be called as a stay-alone function.
Unfortunately this is only as far as JavaScript goes. Up to you to make
sure that any calls would be useless/harmless outside of the class
constructor (or start to cook with function-wrappers to call your
method but it gets too much ugly to discuss - yet technically
possible).



Long answer:
All of the above was about some abstract JavaScript running within the
engine to only purpose to run. It is not true for the absolute majority
of real cases. In real cases you usually run your scripts to accept
user input and to alter graphics context in some way based on this
input. It means that you almost always need to communicate with DOM and
your scripts actually just a bridge between calculations/requests and
user display. By taking MDI-centric approach it is always possible to
represent your model as certain interface elements (form elements,
images, SVG/VML graphics, tables etc.) and certain behaviors you need
to add into it. By using behaviors ("bindings" by Mozilla) you
eliminate all and every problems with incontinence of "this" and lack
of scope modifiers in standard JavaScript. In behaviors your original
code works as an object factory creating a separate instance for each
bound element. This instance is running in its own separate scope
completely independent from the Global scope. The "this" in such
instance and its methods always points to this individual scope (==
current instance scope) and this scope is not accessible from the
Global scope by any means other then public method defined for the
bound element.
All this may lead to an hysteric from a person who learned JavaScript
by the Books of ECMA only :) But in fact it is very flexible and
convenient. Unfortunately it currently covers FF, IE, NN and Camino
only (currently good enough for me, but may be not good enough for
you).
 
R

Richard Cornford

VK said:
A brief answer:
You can't do ...
..., but may be not good enough for you).

What an utterly pointless load of rubbish. As you clearly still don't
understand how the - this - keyword works in javascript it would be a
better idea for you to keep quiet on the subject so you can avoid
making it obvious to everyone else.

Richard.
 
V

VK

Richard said:
What an utterly pointless load of rubbish. As you clearly still don't
understand how the - this - keyword works in javascript it would be a
better idea for you to keep quiet on the subject so you can avoid
making it obvious to everyone else.

I do understand how does "this" work in JavaScript, but I prefer to
talk about it in terms "what I can do and what I can't" rather than in
terms of "what I can't do and here 1000 words explaining why, and
another 1000 words explaining why it must be this way and 100-500 words
add-on explaining that my current needs should never appear if my
brains would work in a semi-normal way" :))

We can start a topic like "this keyword in JavaScript" to discuss the
problem. I assure you that will learn a lot of new and interesting (and
I readily accept that the same will apply to me either).
 
R

Richard Cornford

VK said:
I do understand how does "this" work in JavaScript, but I prefer to
talk about it in terms "what I can do and what I can't" rather than in
terms of "what I can't do and here 1000 words explaining why, and
another 1000 words explaining why it must be this way and 100-500
words add-on explaining that my current needs should never appear
if my brains would work in a semi-normal way" :))

Which does not explain why you have posted 1000 words of incoherent
gibberish.
We can start a topic like "this keyword in JavaScript" to discuss the
problem. I assure you that will learn a lot of new and interesting (and
I readily accept that the same will apply to me either).

You would not learn anything, as you have failed to understand any of
the many expiations of the behaviour of the - this - keyword in
javascript that you have seen. I would learn nothing as I already
understand the subject to the extent that it is possible.

Richard.
 
J

John G Harris

VK said:
A brief answer:
You can't do it in JavaScript because of a specification bug
<snip>

You obviously don't know what the word "bug" means.

John
 
R

Randy Webb

John G Harris said the following on 9/7/2006 3:24 PM:
<snip>

You obviously don't know what the word "bug" means.

VK is lucky to know his name in the mornings.
 
V

VK

John said:
You obviously don't know what the word "bug" means.

<quote>A brief answer:
You can't do it in JavaScript because of a specification bug (because
of well-thought engine mechanics, because of bad implementations of
totally right specifications, because of ... - you really choose the
best from the list or fill your own one: do not start yet another
discussions :)

Because of this ... phenomenon <snip>
</quote>

Be pedantic, sarcastic, nasty, rude, furious, tricky, shifty, ironic
and many many other things you like (if friendly is not an option). But
please don't be silly.
 
V

VK

VK said:
2) Static protected method constructor of a class constructor.

<script>
function method1() {
window.alert('The Glory and the mISERY of JavaScript...');
}
method1.toString = function() {
if ((arguments.caller)
&&(arguments.caller === myConstructor)) {
return method1;
}
else {
return window.alert('Error');
}
}

function myConstructor() {
this.method1 = method1;
}

var obj = new myConstructor();
obj.method1();
method1();
</script>

Uhmm... Just noticed that I grabbed the word for another tune (about
the source dump and functions acting as properties). Should put some
order on my files...

For your case it is the same (using caller property) but much simplier,
no need to override toString method, just put the caller check right
into your function.

Yet you are saying bye-bye to Opera in either case, and if you really
go for it (which is not always an option), then better use behaviors
right away.
 
R

Richard Cornford

VK said:
<quote>A brief answer:
You can't do it in JavaScript because of a specification bug
</quote>

Be pedantic, sarcastic, nasty, rude, furious, tricky, shifty,
ironic and many many other things you like (if friendly is not
an option). But please don't be silly.

You wrote the words "a specification bug", and you even re-quoted them.
If you knew what a bug was you would not have assembled that sequence of
words (except maybe if insane, which had yet to be ruled out).

Richard.
 
R

Richard Cornford

Why don't you give this up as you have been corrected for miss-applying
access modifier terminology often enough to make it clear that you don't
understand what they mean. Not that that 'sentence' makes any sense.

If this is supposed to be "static" why is it being assigned as a
property of the instance?

And if it is supposed to be "static" why is it being called as a method
of the instance?
Uhmm... Just noticed that I grabbed the word for another tune
(about the source dump and functions acting as properties).
Should put some order on my files...

Another loose aggregation of words where sentences might be expected.

... ), then better use behaviors right away.

LOL

Richard.
 
J

John W. Kennedy

Richard said:
You wrote the words "a specification bug", and you even re-quoted them.
If you knew what a bug was you would not have assembled that sequence of
words (except maybe if insane, which had yet to be ruled out).

I don't know.... Wouldn't an inadvertent contradiction constitute a
"specification bug"? (Granted that VK's application of the term is insane.)
 
J

John G Harris

John W. Kennedy said:
I don't know.... Wouldn't an inadvertent contradiction constitute a
"specification bug"? (Granted that VK's application of the term is
insane.)

It is indeed possible for a design/specification decision to be wrong.
For instance, using two-digit year numbers in a language invented in the
1990s was an act of insanity that can rightly be called a bug.

However, merely disagreeing with a designer's choice does not make it a
bug. This is what VK does not understand.

John
 
V

VK

John said:
I don't know.... Wouldn't an inadvertent contradiction constitute a
"specification bug"? (Granted that VK's application of the term is insane.)

By taking an iconified look to each and any *written* specification
(rule, regulation, law) it indeed can be only someone's non-compliance
to the written - therefore *ideal* - model. In the programming aspect
it requires to define a bug as "a system (dis)behavior non-conforming
to the provided specifications for the given system". With such
definition the term "specification bug" indeed doesn't have any sense.

The question is: is it possible for a system to contain an obvious bug
yet do not have a "bug" as it was defined above? I will use again the
"street lights" sample - it comes from the very first programming books
illustrating the idea of right and wrong algorithms.

Let's imagine that the company A Specs, Inc. produced a regulation for
crossing the street by pedestrians:
"When seeing the red light, stop; when seeing the green light - go".
Let's imagine now that the company B Soft, Inc. has to write a program
for some experimental robot-pedestrian using the A Specs, Inc.
regulation (it becomes a block-schema for the program in such case). In
JavaScript that could be:

function mover(lightSeen) {
if (lightSeen == constGreen) {
walkAcross();
}
else if (lightSeen == constRed) {
stayStill();
}
else {
undefinedSitiationHandler();
}
}

Does this program contain a bug as it was defined at the beginning? No
it doesn't - it strictly follows the document from A Specs, Inc. Yet it
does contain a bug you'll discover as soon as you move your robot on
the street. On the first red light it will stop and it will stay until
your restart it. The algorithm is wrong: it doesn't define what to do
after stopped on the red light. A functional subroutine must be
something like:

function mover(lightSeen) {
if (lightSeen == constGreen) {
walkAcross();
}
else if (lightSeen == constRed) {
stayStill();
}
else {
undefinedSitiationHandler();
}
setTimeout('visualPerceiver()',1000);
}

with the perceiver called every second and the result sent to mover().
We had to extend our program beyond the specs. We've got a
*specification bug* we had to compensate in our program.

At the same time as another option B Soft, Inc. may program the robot
exactly as it is said, put all claims on A Specs, Inc. and wait for
better specs to arrive. If new specs are too long to arrive and do not
loose customers, B Soft, Inc. may attach to the robot a timer to reset
the system if it stays on the same place longer than say 20 sec. It is
not a violation/extension of existing specs, as they do not define when
and why would we need to reset the robot. If updated specs never
arrive, there will be generations of robots with the "timer fix". New
engineers coming to B Soft, Inc. will take this as granted.

"it stops and doesn't move - it's OK!
We have a reset timer"

"<this> refuses to point to what we need - it's OK!
this.self / var self = this solves the problem"

Coming back to our moutons :)
I see the incontinence of <this> as a bug. At the same time - and I'm
sure that Mr.Cornford will gladly prove it once over again - it doesn't
contradict any of the current ECMAScript engine specifications.
Expression is expressing, production chain is producting, blah-blah,
blah... everything tip-top. :)

Therefore for me it's a specification bug ("specification error" by
Douglas Crockford) and I call it this way, whether one likes it or not.
Respectively I define a bug more widely as "a fault or defect in a
system or machine". In comparison to the discussed definition given at
the beginning of this post it doesn't fixate on "by specs or against of
them".
 
R

Richard Cornford

Isn't a document that contains a contradiction inevitably non-specific,
and so not a specification in any sense but being named such?
By taking an iconified look to each and any *written*
specification (rule, regulation, law) it indeed can be
only someone's non-compliance to the written - therefore
*ideal* - model. In the programming aspect it requires to
define a bug as "a system (dis)behavior non-conforming to
the provided specifications for the given system". With such
definition the term "specification bug" indeed doesn't have
any sense.

The question is: is it possible for a system to contain an
obvious bug yet do not have a "bug" as it was defined above?
I will use again the "street lights" sample - it comes from
the very first programming books illustrating the idea of
right and wrong algorithms.

Let's imagine that the company A Specs, Inc. produced a regulation for
crossing the street by pedestrians:
"When seeing the red light, stop;

That would be an insane specification; as it tales time to cross a road
and the lights can change almost instantaneously stopping would be a
very unwise response to seeing a red light at any point between
commencing to cross a road and completing the process.
when seeing the green light -
go". Let's imagine ...
... We've got a *specification bug*

We have a poor specification.
we had to compensate in our program.

No, we reject the specification and return it to its author(s) for
correction. Possibly suggesting that "do not commence crossing a road
when a red light can be seen" as a safer and clearer alternative in this
context.

"<this> refuses to point to what we need - it's OK!

The - this - keyword - always refers to what it is specified as
referring to. It is neither unexpected nor undesirable that whatever it
does refer to will be non-relevant in some code, and that other means
will be needed to make references that re relevant.
this.self / var self = this solves the problem"

If a specific object cannot be accessed through the - this - keyword
then accessing it through the scope chain is a completely reasonable
alternative.
Coming back to our moutons :)
I see the incontinence of <this> as a bug.

And still, despite repeated requests, you refuse to explain what
"incontinence" is supposed to mean. The - this - keyword is completely
constant and predictable in its behaviour.
At the same time - and I'm sure that Mr.Cornford will
gladly prove it once over again - it doesn't contradict
any of the current ECMAScript engine specifications.

More likely I would point out that all implementations follow the
specification so any programmer considering using - this - can know with
certainty exactly what will be referred to be - this - in their own
code. This is a situation that allows programming using javascript.
Expression is expressing, production chain is
producting, blah-blah, blah... everything tip-top. :)
Gibberish.

Therefore for me it's a specification bug

Because you cannot cope with reality, but that is mostly a consequence
of your not understanding javascript even to the extent of not knowing
what the code you write is supposed to do.
("specification error" by Douglas Crockford)

Believing that specifying alternative behaviour for the - this - keyword
may have been preferable is reasonable.
and I call it this way, whether one likes it or
not.

Yes, you have never let being told that the statements you make are
false, nonsense, incoherent, incomprehensible, etc, etc, influence your
decision to make them.
Respectively I define a bug more widely as "a fault or
defect in a system or machine".

So a faulty memory chip is a "bug"?
In comparison to the discussed definition given at
the beginning of this post it doesn't fixate on "by
specs or against of them".

The more you write the more I see why you are the worst programmer I
have ever encountered, and the more I suspect that insanity is the only
possible explanation.

Richard.
 
J

John G Harris

I see the incontinence of <this> as a bug.
<snip>

Could you say, clearly and in not many words and with no irrelevant
examples, what this incontinence is.

John
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,170
Latest member
Andrew1609
Top