473,569 Members | 2,735 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

JavaScript Variable Scoping and Execution Contexts

Hello,
I have a question about how prototyping relates to variables and their
scope.

Given the following code:
~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
var ParentObject = function()
{
var objectName = "ParentObje ct";

this.getObjectN ame = function()
{
return objectName;
}
this.setObjectN ame = function( newObjectName )
{
objectName = newObjectName;
}
}

var ChildObject = function()
{
ParentObject.ap ply(this, arguments);

this.tryToRefer enceObjectNameV ar = function()
{
var text = null;
// Attempt to reference the variable "objectName ",
// which was created in ParentObject.
try
{
text = "ChildObjec t's \"objectName \"" +
" variable is \"" + objectName + "\"";
}
catch( error )
{
alert( "Error: " + error.name +
" at " + "line: " + error.lineNumbe r + "\n" +
"\"" + error.message + "\"\n" +
"Stack:\n" + error.stack + "\n" );
}
return text;
}
}

var child = new ChildObject();
child.tryToRefe renceObjectName Var();
~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
The last call throws this ReferenceError:

Error: objectName is not defined

Is this because prototyping, which I have done by calling the "apply"
method of a constructor, creates an independent execution context
that cannot be accessed from the "child" object's execution context? In
other words,
when I call

child.getObject Name();
child.tryToRefe renceObjectName Var();

are two (or several) different execution contexts being referenced? How is
the
JavaScript interpreter handling this?

TIA,
Greg
Jul 23 '05 #1
5 1977
On Sat, 4 Sep 2004 12:00:09 -0500, Greg Swindle <gr**@swindle.n et> wrote:

[snip]
var ChildObject = function()
{
ParentObject.ap ply(this, arguments);
I must say that I'm surprised this approach works. However, a quick read
of ECMA-262 suggests it should but I wouldn't use it. The apply method is
relatively recent addition to the language. The prototype object is widely
supported and will yield the same net effect

[snip]
The last call throws this ReferenceError:

Error: objectName is not defined

Is this because prototyping, which I have done by calling the "apply"
method of a constructor,
A function is only really a constructor when it's called using the new
operator, which invokes the [[Construct]] internal method. What you've
effectively done is pass object, child, to a function which has tacked on
two properties: getObjectName and setObjectName. There isn't really any
inheritance here.
creates an independent execution context that cannot be accessed from
the "child" object's execution context?


When a function is called, a new execution context is created. The local
variables, inner functions and formal parameters are added to the
activation object for that function.

When an inner function is defined, it's [[Scope]] property (what it uses
to look-up identifiers) is set to the activation object of the function
which defines it. So, in ParentObject, the [[Scope]] property of
getObjectName and setObjectName is set to the activation object of the
ParentObject function. This allows them to reference the local variable
objectName.

However, as I said above, all you're doing when you call apply in your
code is add extra properties to the ChildObject object. There is no
modification of the scope chain, and so you can't access the local
variable. In fact, you will never be able to access it without inner
functions. You'll either have to place objectName in a common context or
use accessor functions.

What exactly are you trying to accomplish? There might be some other
possibilities.

For more information on closures, see the FAQ notes:

<URL:http://www.jibbering.c om/faq/faq_notes/closures.html>

Hope that helps,
Mike

--
Michael Winter
Replace ".invalid" with ".uk" to reply by e-mail.
Jul 23 '05 #2
Mike,

Yes, that helps, thanks. After I wrote this email I found the very article
you cite, and it was quite enlightening.

Some comments:
On Sat, 4 Sep 2004 12:00:09 -0500, Greg Swindle <gr**@swindle.n et> wrote:

[snip]
var ChildObject = function()
{
ParentObject.ap ply(this, arguments);
I must say that I'm surprised this approach works. However, a quick read
of ECMA-262 suggests it should but I wouldn't use it. The apply method is
relatively recent addition to the language. The prototype object is widely
supported and will yield the same net effect


I "discovered " this when I was playing around with the Decorator design
pattern and wanted a way to
simulate calling a parent class's constructor function (e.g., like calling
"super" in Java). Because this was a while back,
and because I did not yet know about either "apply" or "call," I prototyped
like this:

function ChildObject( someArg )
{
this.temp = ParentObject;
this.temp(someA rg );
delete this.temp;
}

In short, I wanted to not only prototype, but also call the function being
prototyped. For a full example,
please see the source code here:

http://www.swindle.net/Content/Greg/...sDecorator.htm

[snip]
A function is only really a constructor when it's called using the new
operator, which invokes the [[Construct]] internal method. What you've
effectively done is pass object, child, to a function which has tacked on
two properties: getObjectName and setObjectName. There isn't really any
inheritance here
Strictly speaking, is there *ever* inheritance *anywhere* in JavaScript?

[snip]
What exactly are you trying to accomplish? There might be some other
possibilities.


Good question. I'm trying to write JavaScript in a way that makes it
resemble more familiar OO
code (e.g., Java, C++, C#). This is why I like using function literals.
Writing functions
as literals has several advantages to me:

1. Assigning a function literal to a variable makes the variable "appear"
more like an object.
2. I can immediately "tack on" properties and methods to it before any
internal operations are
called, thereby simulating multiple inheritance/interface implementation.
3. I can embed functions within my object, which simulates privately scoped
functions in class-
based OO languages. With functions nestled inside my function's curly
braces, it "looks" clearer that these
functions are only intended to support the overall "object."
4. It allows me to simulate privately scoped variables, which effects a
stronger form of data
encapsulation. Tangentially, that's one of the few things that really irks
me about Python: all class
variables are public, which frankly sucks.
5. Finally, it directly exposes one of JavaScript's most powerful features:
functions are also data.
Therefore, the following code:

var ChildObject = function( childName, childAge )
{

}

makes more sense to me when I construct ChildObject with the "new" keyword,
as opposed
to constructing a function.

Thanks for wading through the verbosity. I welcome your comments.

Regards,
Greg
Jul 23 '05 #3
On Sat, 4 Sep 2004 21:04:48 -0500, Greg Swindle <gr**@swindle.n et> wrote:

[snip]
http://www.swindle.net/Content/Greg/...sDecorator.htm
Sorry to nit-pick...

HTML pages should always contain a document type declaration. When
present, it usually forces the browser to render the page according to
standards, resulting in a much more consistent presentation across user
agents. All new pages should be written using a combination of Strict HTML
and CSS, with Transitional HTML reserved for legacy pages.

Valid HTML requires that SCRIPT elements include the type attribute. The
language attribute has been deprecated in favour of type and should not be
used any more. Similarly, script hiding through the use of SGML comment
delimiters is an anachronism.

/* c - Currency symbol to use (defaults to none).
* g - Grouping symbol (defaults to none).
*/
Number.prototyp e.toCurrency = function(c, g) {
c = c || ''; g = g || '';
var p = (0 > this) ? '-' + c : c,
m = new String(Math.rou nd(Math.abs(thi s))),
i = '', f, j, dP = 2, gS = 3;

while(m.length < 1 + dP) {m = '0' + m;}
f = m.substring((j = m.length - dP));
if(g) {
while(j > gS) {i = g + m.substring(j - gS, j) + i; j -= gS;}
}
return p + m.substring(0, j) + i + '.' + f;
}

The code above is less likely to introduce errors as no multiplication or
division is required. This means that the number should represent pennies
not larger denominations. However, when it comes to financial
calculations, it always best to use integer arithmetic.

[snip]
Strictly speaking, is there *ever* inheritance *anywhere* in JavaScript?
Yes. You use it in the URL you presented.

You can add an object as the prototype for a constructor function. When
you instantiate an object from that constructor, it will inherit the
properties of its prototype. You should also use the prototype object to
add members that do not need direct access via a closure to the formal
arguments or local variables of the constructor (that is, when they do not
need to "privaledge d").

function Parent_firstMet hod() {
}
function Parent() {
// Uses an argument or local variable:
this.secondMeth od = function() {};
}
Parent.prototyp e.firstMethod = Parent_firstMet hod;
Parent.prototyp e.thirdMethod = function() {};

function Child() {
}
Child.prototype = new Parent();

var myChild = new Child();
myChild.firstMe thod();
myChild.secondM ethod();
myChild.thirdMe thod();

Unfortunatly, this approach doesn't allow you to pass arguments at will to
the parent; you can only pass an argument on the Child.prototype line
above.

What you've been doing is a modified form of object augmentation: take an
existing object and add other members to it. This is perfectly viable and
you're not the first to use it, but it's not really inheritance.

You might want to take a look at Douglas Crockford's web site. He has some
interesting articles on OO Javascript.

<URL:http://www.crockford.c om/>

[snip]
I'm trying to write JavaScript in a way that makes it resemble more
familiar OO code (e.g., Java, C++, C#). This is why I like using
function literals.
Do you mean function expressions?
Writing functions as literals has several advantages to me:
[snip]

The ability to encapsulate related functions and hide data is extremely
useful.
var ChildObject = function( childName, childAge )
{
}

makes more sense to me when I construct ChildObject with the "new"
keyword, as opposed to constructing a function.


Each to their own. :)

I use the Java naming scheme: start classes (in this case, constructor
functions) with capitals and normal functions with lowercase. That's
enough for me.

Mike

--
Michael Winter
Replace ".invalid" with ".uk" to reply by e-mail.
Jul 23 '05 #4
"Greg Swindle" <gr**@swindle.n et> writes:
Strictly speaking, is there *ever* inheritance *anywhere* in JavaScript?
JavaScript (or really ECMAScript) is a prototype based object oriented
language. That means that there are no classes, so inheritance cannot
be between classes as in class based languages. Instead, prototype
based inheritance is between objects.

Prototype based inheritance is implemented using a "protoype
chain". When you look up a property of an object, the language first
checks whether the object has that property on itself. If it hasn't,
it starts traversing the prototype chain and checking for the property
on the prototypes. Almost all objects has a non-empty prototype chain
with the (original) value of Object.prototyp e at the end (the
exception is Object.prototyp e itself, which has an empty prototype
chain).

Every time you create an object using a constructor function, call it
Foo, the value of Foo.prototype is used as the prototype of the new
object.

Example:
---
function Foo(){} // constructor function with no initialization
var object = new Object(); // new object
object.bar = 42; // with properties bar
object.baz = "hello world";// and baz
Foo.prototype = object; // set as prototype for objects created by Foo
var foo = new Foo(); // create new object from Foo
foo.bar = 37; // set property bar of foo.
alert([foo.bar, foo.baz]); // alerts: 37, hello world

// The link to the prototype object is live,
// it's not just the properties that are inherited
// but the entire object:
object.bif = true; // change prototype object property after creation
alert(foo.bif); // alerts: true
---
Good question. I'm trying to write JavaScript in a way that makes it
resemble more familiar OO code (e.g., Java, C++, C#).


You are in for some hard work, because the difference between a
prototype based language and a class based one is at the fundamental
level. There are no classes in Javascript.

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleD OM.html>
'Faith without judgement merely degrades the spirit divine.'
Jul 23 '05 #5
Lasse Reichstein Nielsen wrote:
"Greg Swindle" <gr**@swindle.n et> writes:
Good question. I'm trying to write JavaScript in a way that makes it
resemble more familiar OO code (e.g., Java, C++, C#).


You are in for some hard work, because the difference between a
prototype based language and a class based one is at the fundamental
level. There are no classes in Javascript.

^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^
prior to version 2, or prior to ECMAScript 4 implementations like JScript 6.
Pointed"JFTR"Ea rs
--
.... the gentle sound of crashing software ...
Jul 23 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

10
6692
by: Andy Fish | last post by:
Hi, can anybody put forward a sensible argument javascript's behaviour of creating a new global variable whenever I assign to a previously undeclared variable. I can't beleive this is just for the sake of convenience (surely we learned this much from basic). here's my proposal: all "global" (document scope) variables must be declared by...
8
4290
by: Sergio Otoya | last post by:
Hi all, I need to add an input hidden field to an existing form (post). I have tried a couple things like adding the '<INPUT type=hidden name=idSelectedURL value=http://server/documents>' to the innerHTML of the form but it fails. ie
7
2182
by: Michael G | last post by:
I am a little surprised that the following that $x is visible outside of the scope in which it is (?)defined(?) (not sure if that is the correct term here). I am trying to find where in the php docs that this is discussed. Haven't found anything yet. Any help appreciated. I am also assuming that the following scoping rule holds for other...
136
9250
by: Matt Kruse | last post by:
http://www.JavascriptToolbox.com/bestpractices/ I started writing this up as a guide for some people who were looking for general tips on how to do things the 'right way' with Javascript. Their code was littered with document.all and eval, for example, and I wanted to create a practical list of best practices that they could easily put to...
13
2090
by: Andy Baxter | last post by:
Can anyone recommend a good online guide to using objects in javascript? The book I bought (DHTML Utopia) suggests using objects to keep the code clean and stop namespace clashes between different parts of the code, but as far as I can see, the way objects work in javascript is quite awkward. I had it working the way they suggest in the book,...
9
1919
by: NevilleDNZ | last post by:
Can anyone explain why "begin B: 123" prints, but 456 doesn't? $ /usr/bin/python2.3 x1x2.py begin A: Pre B: 123 456 begin B: 123 Traceback (most recent call last): File "x1x2.py", line 13, in ? A() File "x1x2.py", line 11, in A
10
12783
by: John Passaniti | last post by:
(Note: This is not the same message I posted a week or so ago. The problem that prevented my previous attempt to work was a silly error in the template system I was using. This is a problem involving variable scope in JavaScript.) I have a lot of code that generates HTML on the fly. This code has tags with id attributes derived from...
1
25638
pbmods
by: pbmods | last post by:
VARIABLE SCOPE IN JAVASCRIPT LEVEL: BEGINNER/INTERMEDIATE (INTERMEDIATE STUFF IN ) PREREQS: VARIABLES First off, what the heck is 'scope' (the kind that doesn't help kill the germs that cause bad breath)? Scope describes the context in which a variable can be used. For example, if a variable's scope is a certain function, then that...
3
1642
by: Jonathan Fine | last post by:
As subject. By 'before' I mean before in the file, not in time. Here's a file === $ cat wierd.js f() function f(){print('hi')} f() function f(){print('ho')} f()
0
7694
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7609
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7921
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
8118
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7666
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
7964
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
6278
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
1
5504
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
1
2107
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.