473,396 Members | 2,154 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Can you recommend a tutorial on using objects in javascript?

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, and it was going OK
until I wanted to call one object method from another - I couldn't find a
syntax for this that worked. I tried following a guide I found online, and
the way they say to do it means putting 'this.' before practically
everything, and the code still doesn't work. I'm tempted just to forget
about objects and do the whole thing as separate functions, but I still
don't quite want to do this.

please help!

--
http://www.niftybits.ukfsn.org/

remove 'n-u-l-l' to email me. html mail or attachments will go in the spam
bin unless notified with [html] or [attachment] in the subject line.

May 23 '06 #1
13 2062
Andy Baxter wrote:
Can anyone recommend a good online guide to using objects in
javascript?
Since everything in javascript is an object, pretty much doing _anything_
involves using objects :)
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.
"Different than most people are used to" != awkward.
Once you get used to it, it's easily understood.

Using objects as a "namespace" to encapsulate functions is a good idea.

A simple example:

var MyLib = {};
MyLib.funcA = function() { ... }
myLib.funcB = function() { ... }
I had it working the way they suggest in
the book
What did they suggest?
and it was going OK until I wanted to call one object
method from another - I couldn't find a syntax for this that worked.
Depends on exactly what kind of syntax you were using.

For example:

var MyLib2 = {};
MyLib2.funcC = function() { MyLib.funcA(); }
I tried following a guide I found online, and the way they say to do
it means putting 'this.' before practically everything, and the code
still doesn't work.
Using "this" only applies to instantiated objects. If you're only using
objects as a namespace, then you won't be instantiating them and won't have
any use for 'this'.
I'm tempted just to forget about objects and do
the whole thing as separate functions, but I still don't quite want
to do this.


Depending on exactly what you're doing, this may not be a bad thing. Global
functions are not evil, especially if you have full control of the page. If
you are building reusable code, however, encapsulating functionality into a
namespace is a good idea.

--
Matt Kruse
http://www.JavascriptToolbox.com
http://www.AjaxToolbox.com
May 23 '06 #2
Matt Kruse said:
Andy Baxter wrote:
and it was going OK until I wanted to call one object
method from another - I couldn't find a syntax for this that worked.


Depends on exactly what kind of syntax you were using.

For example:

var MyLib2 = {};
MyLib2.funcC = function() { MyLib.funcA(); }


In the code below, the line I've marked doesn't work - it never reaches
the pano.moveImages() function. If I change it to just 'moveImages;'
(which is what I tried first), it gives an error: 'moveImages is not
defined'. I'm confused about this, because referring to object properties
like mouseDown and pan from inside the functions works fine without adding
'pano.' in front, but referring to one of the object methods doesn't. If
you have any general comments on the way I've written this, I'd appreciate
that too, as this is the first program I've written in javascript.

// Panorama script
// By Andy Baxter, May 2006

function showMessage(str) {
var rep=document.getElementById("message1");
rep.innerHTML=str;
}

function showMessage2(str) {
var rep=document.getElementById("message2");
rep.innerHTML=str;
}
var pano = {
// initialisation for the panorama.
// pixels to move when mouse is at full left / right.
scale: 0,
// mouse status.
mouseDown: 0,
mouseX: 0,
mouseY: 0,
// ratio that panorama is panned to left.
pan: 0,
// size of pano image [width,height]
imgSize: 0,
scaledImgSize: 0,
// references to DOM objects.
panoDiv: 0,
panoPic1: 0,
init: function() {
// initialise variables;
scale=30;
mouseDown=0;
mouseX=0;
mouseY=0;
pan=0;
panoDiv = document.getElementById("panoDiv");
panoPic1 = document.getElementById("panoImage1");
panoPic2 = document.getElementById("panoImage2");
imgSize=new Array(2);
imgSize[0]=3996;
imgSize[1]=500;
var imgScale=parseInt(panoDiv.style.height)/imgSize[1];
scaledImgSize=new Array(2);
scaledImgSize[0]=imgScale*imgSize[0];
scaledImgSize[1]=imgScale*imgSize[1];
panoPic1.style.width=scaledImgSize[0]+"px";
panoPic1.style.height=scaledImgSize[1]+"px";
panoPic2.style.width=scaledImgSize[0]+"px";
panoPic2.style.height=scaledImgSize[1]+"px";
// connect events.
dojo.event.connect(panoDiv, "onmousedown", pano, "onMouseDown");
dojo.event.connect(panoDiv, "onmouseup", pano, "onMouseUp");
dojo.event.connect(panoDiv, "onmousemove", pano, "onMouseMove");
dojo.event.connect(panoPic1, "onmousemove", pano, "stopdefault");
dojo.event.connect(panoPic1, "onmousedown", pano, "stopdefault");
dojo.event.connect(panoPic1, "onmouseup", pano, "stopdefault");
dojo.event.connect(panoPic1, "onmouseclick", pano, "stopdefault");
setInterval( pano.mover ,100);
},
mover: function() {
var d=new Date();
showMessage("mouseX: "+mouseX+" mouseY: "+mouseY+" mousedown:"+mouseDown+" secs:"+d.getSeconds());
// called every so often to move the panorama.
if (! mouseDown) return;
var width=parseInt(panoDiv.style.width);
// work out how much to move based on position in the viewport.
var offset=-Math.round(scale*2*((mouseX-width/2)/width));
pan -= offset/scaledImgSize[0];
if (pan <0) {
pan +=1;
}
else if (pan >1) {
pan -=1;
}
**** next line doesn't work *****
pano.moveImages;
//panoPic1.style.left="-"+(pan * scaledImgSize[0])+"px";
//panoPic2.style.left=((-pan*scaledImgSize[0])+scaledImgSize[0])+"px";
},
clipImage: function(img) {
// clip an image to make it fit in the viewport.
var pos=parseInt(img.style.left);
var width=parseInt(img.style.width);
var divWidth=parseInt(panoDiv.style.width);
var leftClip, rightClip;
// clip off the left side if the image crosses the left edge of the viewport.
leftClip=(pos<0)?-pos:0;
// and the same for the right side.
rightClip=(pos+width>divWidth)?pos+divWidth:width;
img.style.clip="rect(0px,"+rightClip+"px,"+panoDiv .style.height+","+leftClip+"px)";
},
moveImages: function() {
// move images to a position depending on the pan value.
alert(here);
showMessage2("offset: "+offset+" pic x:"+panoPic1.style.left+" pan:"+pan);
panoPic1.style.left="-"+(pan * scaledImgSize[0])+"px";
panoPic2.style.left=((-pan*scaledImgSize[0])+scaledImgSize[0])+"px";
// clip the images according to where they are in the viewport.
//this.clipImage(panoPic1);
//this.clipImage(panoPic2);
},
stopDefault: function(evt) {
evt.preventDefault;
},
onMouseDown: function(evt) {
mouseDown=-1;
evt.stopPropagation;
evt.preventDefault;
},
onMouseUp: function(evt) {
mouseDown=0;
evt.stopPropagation;
evt.preventDefault;
},
onMouseMove: function(evt) {
// update the mouse coords.
mouseX=evt.clientX-dojo.style.getTotalOffset(panoDiv,"left",0);
mouseY=evt.clientY-dojo.style.getTotalOffset(panoDiv,"top",0);
evt.stopPropagation;
evt.preventDefault;

}
}

dojo.addOnLoad(pano.init);

**** HTML file follows ****

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN"> <html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="content-type">
<title>Panorama-test</title>
<script type="text/javascript" src="js/dojo/dojo.js"></script> <script
type="text/javascript" src="js/pano.js"></script>
</head>
<body>
<h1 id="heading">Panorama Test
</h1>
<p id="message1">&nbsp;</p>
<p id="message2">&nbsp;</p>
<div style="position: relative; top: 0px; left: 0px;"> <div id="panoDiv"
style="position: absolute; top: 0px; left: 30px; width: 700px; height:
400px; clip: rect(0px, 700px, 400px, 0px);"><img id="panoImage1"
style="position: absolute; width: auto; height: 400px; left: 0px;
z-index: 10;" alt="" src="pano2.jpg"><img id="panoImage2"
style="position: absolute; width: auto; height: 400px; left: 0px;
z-index: 9;" alt="" src="pano2.jpg"></div>
</div>
<p>&nbsp;</p>
</body>
</html>


--
http://www.niftybits.ukfsn.org/

remove 'n-u-l-l' to email me. html mail or attachments will go in the spam
bin unless notified with [html] or [attachment] in the subject line.

May 23 '06 #3
Andy Baxter wrote:
Matt Kruse said:
Andy Baxter wrote:
and it was going OK until I wanted to call one object
method from another - I couldn't find a syntax for this that worked. Depends on exactly what kind of syntax you were using.

For example:

var MyLib2 = {};
MyLib2.funcC = function() { MyLib.funcA(); }


In the code below, the line I've marked doesn't work - it never reaches
the pano.moveImages() function. If I change it to just 'moveImages;'
(which is what I tried first), it gives an error: 'moveImages is not
defined'. I'm confused about this, because referring to object properties
like mouseDown and pan from inside the functions works fine without adding
'pano.' in front, but referring to one of the object methods doesn't. If
you have any general comments on the way I've written this, I'd appreciate
that too, as this is the first program I've written in javascript.

// Panorama script
// By Andy Baxter, May 2006

function showMessage(str) {
var rep=document.getElementById("message1");
rep.innerHTML=str;
}


Don't post code with tabs, use 2 or 4 spaces for indentation.

[...]
var pano = {
// initialisation for the panorama.
// pixels to move when mouse is at full left / right.
scale: 0,
// mouse status.
mouseDown: 0,
mouseX: 0,
mouseY: 0,
// ratio that panorama is panned to left.
pan: 0,
// size of pano image [width,height]
imgSize: 0,
scaledImgSize: 0,
// references to DOM objects.
panoDiv: 0,
panoPic1: 0,
init: function() {
You might find it easier to add methods using:

pano.init = function()
{
// function body
}
// initialise variables;
scale=30;
mouseDown=0;
mouseX=0;
mouseY=0;
pan=0;

You must be very careful with creating variables this way. Omitting
'var' means that before pano.init() is called, they are all undefined.
After pano.init() is called, they are all global variables. Perhaps
they should be properties of pano?

panoDiv = document.getElementById("panoDiv");
panoPic1 = document.getElementById("panoImage1");
panoPic2 = document.getElementById("panoImage2");
Some feature detection for getElementById before attempting to use it
would be good, particularly inside an init function. If it's not
supported, deal with it before going any further.

imgSize=new Array(2);
imgSize[0]=3996;
imgSize[1]=500;
You can initialise the array as:

imgSize = [3996, 500];
[...] // connect events.
dojo.event.connect(panoDiv, "onmousedown", pano, "onMouseDown"); [...] dojo.event.connect(panoPic1, "onmouseclick", pano, "stopdefault");
You didn't inlcude the dojo library, so lots of errors thrown here...

[...]
} **** next line doesn't work *****
pano.moveImages;


If you want to call pano.moveImages, use '()':

pano.moveImages();

The above line just returns a reference to the function and does nothing
with it. It would make more sense to place the call after the function
declaration.

[...]
--
Rob
Group FAQ: <URL:http://www.jibbering.com/faq/>
May 24 '06 #4

Andy Baxter wrote:
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, and it was going OK
until I wanted to call one object method from another - I couldn't find a
syntax for this that worked. I tried following a guide I found online, and
the way they say to do it means putting 'this.' before practically
everything, and the code still doesn't work. I'm tempted just to forget
about objects and do the whole thing as separate functions, but I still
don't quite want to do this.

If you are looking for class-based inheritance you can simulate it.

http://www.kevlindev.com/tutorials/j...ance/index.htm

Here is something I haven't studied yet

http://www.crockford.com/javascript/inheritance.html

- Peter

May 24 '06 #5
RobG said:
Andy Baxter wrote:
// Panorama script
// By Andy Baxter, May 2006

function showMessage(str) {
var rep=document.getElementById("message1");
rep.innerHTML=str;
}
Don't post code with tabs, use 2 or 4 spaces for indentation.

[...]
var pano = {
// initialisation for the panorama.
// pixels to move when mouse is at full left / right.
scale: 0,
// mouse status.
mouseDown: 0,
mouseX: 0,
mouseY: 0,
// ratio that panorama is panned to left.
pan: 0,
// size of pano image [width,height]
imgSize: 0,
scaledImgSize: 0,
// references to DOM objects.
panoDiv: 0,
panoPic1: 0,
init: function() {


You might find it easier to add methods using:

pano.init = function()
{
// function body
}


I liked that syntax because it's clearer and everything is wrapped up in
the same chunk.
// initialise variables;
scale=30;
mouseDown=0;
mouseX=0;
mouseY=0;
pan=0;

You must be very careful with creating variables this way. Omitting
'var' means that before pano.init() is called, they are all undefined.
After pano.init() is called, they are all global variables. Perhaps
they should be properties of pano?


I thought they were - I was assuming that once I'd declared them as
properties of pano, then after that I could refer to them as such without
the 'var'. I think I'm still thinking javascript is like C++ when it
isn't.
panoDiv = document.getElementById("panoDiv"); panoPic1 =
document.getElementById("panoImage1"); panoPic2 =
document.getElementById("panoImage2");


Some feature detection for getElementById before attempting to use it
would be good, particularly inside an init function. If it's not
supported, deal with it before going any further.


OK.
imgSize=new Array(2);
imgSize[0]=3996;
imgSize[1]=500;


You can initialise the array as:

imgSize = [3996, 500];


OK.
[...]
// connect events.
dojo.event.connect(panoDiv, "onmousedown", pano, "onMouseDown");

[...]
dojo.event.connect(panoPic1, "onmouseclick", pano, "stopdefault");


You didn't inlcude the dojo library, so lots of errors thrown here...


It's included in the html file.

}
**** next line doesn't work *****
pano.moveImages;


If you want to call pano.moveImages, use '()':


thanks - that does the trick.
--
http://www.niftybits.ukfsn.org/

remove 'n-u-l-l' to email me. html mail or attachments will go in the spam
bin unless notified with [html] or [attachment] in the subject line.

May 24 '06 #6
Andy Baxter <ne***@earthsong.null.free-online.co.uk> writes:
RobG said:
Andy Baxter wrote:
var pano = {
// initialisation for the panorama.
// pixels to move when mouse is at full left / right.
scale: 0,
// mouse status.
mouseDown: 0, ..... // initialise variables;
scale=30;
mouseDown=0;
....
You must be very careful with creating variables this way. Omitting
'var' means that before pano.init() is called, they are all undefined.
After pano.init() is called, they are all global variables. Perhaps
they should be properties of pano?


I thought they were - I was assuming that once I'd declared them as
properties of pano, then after that I could refer to them as such without
the 'var'. I think I'm still thinking javascript is like C++ when it
isn't.


You are. Scoping in Javascript is not as automatic as in, e.g., C++ or
Java.

To assign a property to an object, you must refer to the object, so
you should write
this.scale = 30;
this.mouseDown = 0;
etc.

As a shorthand, that should be used carefully, you can open an object
as a scope with the "with" statement:

with(this) {
scale = 30;
mouseDown = 0;
// ..
}

It will make properties of the "this" object appear as variables in
the created scope. You should be careful about using any other
variables than the ones you know are there, since there is no way
of knowing what unknown properties an object by have in some
obscure browser or an environment where Object.prototype has been
"enhanced".
/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
May 24 '06 #7
Lasse Reichstein Nielsen wrote:
To assign a property to an object, you must refer to the object, so
you should write
this.scale = 30;
this.mouseDown = 0;
etc.

As a shorthand, that should be used carefully, you can open an object
as a scope with the "with" statement:

with(this) {
scale = 30;
mouseDown = 0;
// ..
}

It will make properties of the "this" object appear as variables in
the created scope.


No, it will not. Instead, this is not different than using no `with'
statement. Exactly because the meaning of write and read access differ
within a with-block, the `with' statement is deprecated.

// assignment to undeclared variable bar
function Foo() { with (this) { bar = 42; } }

// reference to undefined property (new Foo()).bar
(new Foo()).bar

// 42
bar
PointedEars
--
Multiple exclamation marks are a sure sign of a diseased mind.
-- Terry Pratchett
May 25 '06 #8
Thomas 'PointedEars' Lahn <Po*********@web.de> writes:
Lasse Reichstein Nielsen wrote:
with(this) {
scale = 30;
mouseDown = 0;
// ..
}

It will make properties of the "this" object appear as variables in
the created scope.


No, it will not.


Yes, it will.

What it will not do is to make assignments to non-properties create
properties. The existing properties *will* work as variables in
the created scope, assignment and all.

var x = {foo:37};
with(x) {
foo = 42;
bar = "not";
}
alert([x.foo,bar]); // 42,"not"
Instead, this is not different than using no `with'
statement. Exactly because the meaning of write and read access differ
within a with-block, the `with' statement is deprecated.
The reason use of the with statment is not encouraged is that it
is hard to control which variables are introduces, since properties
of objects can be introduced by many different and unpredictable
sources, both the browser and other code.
// assignment to undeclared variable bar
function Foo() { with (this) { bar = 42; } }


The difference from the example given is that "bar" is not a property
of the "this" object at the point of the assignment. Had it been, that
property would have been assigned to.

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
May 25 '06 #9

Matt Kruse wrote:

Using objects as a "namespace" to encapsulate functions is a good idea.
<snip>
If
you are building reusable code, however, encapsulating functionality into a
namespace is a good idea.


And there are two other current threads here that are debating the pros
and cons of this.

Matt, I'm curious what you think about the perfomance loss due to the
extra '.' resolution of a simulated namespace. The other option is
using a prefix to make things unique.

Peter

May 25 '06 #10
Lasse Reichstein Nielsen wrote:
Thomas 'PointedEars' Lahn <Po*********@web.de> writes:
Lasse Reichstein Nielsen wrote:
with(this) {
scale = 30;
mouseDown = 0;
// ..
}

It will make properties of the "this" object appear as variables in
the created scope.


No, it will not.


Yes, it will.

What it will not do is to make assignments to non-properties create
properties. The existing properties *will* work as variables in
the created scope, assignment and all.

var x = {foo:37};
with(x) {
foo = 42;
bar = "not";
}
alert([x.foo,bar]); // 42,"not"


You miss the point. It works with `x.foo' because `x' was declared in that
execution context and therefore becomes a property of the Variable Object
of that context; it works with `bar' because `bar' is created as a property
of the Global Object that is accessed through the scope chain. It has
nothing to do with having "properties of the 'this' object appear as
variables in the created scope"; in fact, scoping is explicitly _not_ used
for `bar'.
Instead, this is not different than using no `with'
statement. Exactly because the meaning of write and read access differ
within a with-block, the `with' statement is deprecated.


The reason use of the with statment is not encouraged is that it
is hard to control which variables are introduces, since properties
of objects can be introduced by many different and unpredictable
sources, both the browser and other code.


Your inability to recognize `bar' being created as a property of the Global
Object directly instead of the corresponding execution context's Variable
Object (provided that they are different) is reason enough to demonstrate
that the `with' statement should not be used at all.
// assignment to undeclared variable bar
function Foo() { with (this) { bar = 42; } }


The difference from the example given is that "bar" is not a property
of the "this" object at the point of the assignment. Had it been, that
property would have been assigned to.


Come on, the whole point of that was to show that the `with' statement's
meaning is not always what you would expect using common sense. Had a
`bar' property been created before with

this.bar = 23;

we probably would not have had a need for the `with' statement in the
first place.
PointedEars
--
When you have eliminated all which is impossible, then
whatever remains, however improbable, must be the truth.
-- Sherlock Holmes in Sir Arthur Conan Doyle's
"The Blanched Soldier"
May 26 '06 #11
pe**********@gmail.com wrote:
Matt, I'm curious what you think about the perfomance loss due to the
extra '.' resolution of a simulated namespace. The other option is
using a prefix to make things unique.


Until someone does a performance test which simulates realistic code
execution and demonstrates a performance decrease when resolving
"Object.function" instead of "function" I'll continue to consider it mental
masturbation.

Computers are fast. Unless you're writing extremely CPU-intensive operations
(which almost never happens in a webapp) then things like this won't matter
in any realistic situation. Unless someone proves me wrong ;)

--
Matt Kruse
http://www.JavascriptToolbox.com
http://www.AjaxToolbox.com
May 26 '06 #12
Thomas 'PointedEars' Lahn <Po*********@web.de> writes:
Lasse Reichstein Nielsen wrote:
Thomas 'PointedEars' Lahn <Po*********@web.de> writes:
Lasse Reichstein Nielsen wrote:
with(this) {
scale = 30;
mouseDown = 0;
// ..
}

It will make properties of the "this" object appear as variables in
the created scope.

No, it will not.
Yes, it will.

What it will not do is to make assignments to non-properties create
properties. The existing properties *will* work as variables in
the created scope, assignment and all.

var x = {foo:37};
with(x) {
foo = 42;
bar = "not";
}
alert([x.foo,bar]); // 42,"not"


You miss the point. It works with `x.foo' because `x' was declared in that
execution context and therefore becomes a property of the Variable Object
of that context;


The name "x" is irrelevant here, what matters is that "foo" is a property
of the object used as parameter of the "with" statement, and "bar" is not.

I repeat my initial statement:

"with(this){...}" will make properties of the "this" object appear as
variables in the created scope.

And it will. And it will do nothing else. It won't change the variable
object of the execution context, or any other property of variable
creation, so you don't get a new way of creating new properties of the
parameter object. You still have to do that with "this.newProperty=...".
it works with `bar' because `bar' is created as a property
of the Global Object that is accessed through the scope chain. It has
nothing to do with having "properties of the 'this' object appear as
variables in the created scope"; in fact, scoping is explicitly _not_ used
for `bar'.
The mention of the "this" object was only as a reference to the parameter
of the "with" statement in the OP's code.

We agree that scoping is not used for "bar", which was exactly what my
example was trying to show, although apprently not very clearly.

When you do:
with(someObject) {
// someCode
}
then all properties of someObject, direct and inherited, enumerable
and not, become available in the scope chain used to execute
"someCode", but someObject does *not* become the variable object
of the execution context.

Reading a variable name that corresponds to a property of "someObject"
will read that property. Writing to a variable name that corresponds
to a property of "someObject" will resolve to and assign to that
property. And the typeof operator will work with these variables too.

All other uses of variables, not corresponding to a property of
"someObject", works just as they would outside the "with" block.

So, more commented:

function test(x) {
with(x) {
foo = 42; // "foo" resolves to x.foo
bar = 42; // "bar" fails to resolve, so creates [globalobject].bar
var baz = 42; // "baz" is created in local variable object, not x
}
// foo is property of x
alert([window.foo, x.foo, typeof foo]); // undefined,42,undefined
// bar is property of global object (window)
alert([window.bar, x.bar, typeof bar]); // 42,unedfined,number
// baz is property of local variable object, and nothing else
alert([window.baz, x.baz, typeof baz]); // undefined,undefined,number
}
test({foo:undefined});

Your inability to recognize `bar' being created as a property of the Global
Object directly instead of the corresponding execution context's Variable
Object (provided that they are different) is reason enough to demonstrate
that the `with' statement should not be used at all.
Oh, I'm quite capable of recognizing it, although my explanation
apparently haven't shown that clearly enough.

Reading or writing to a variable inside a "with" block is different
from doing so outside the "with" block if, and only if, the variable
name is a property of the parameter object.

Since "bar" was not a property of "x" in the example, the assignment
to "bar" works just as if it was not inside a "with" block, and there
was not a variable of that name in scope, so it creates a property of
the global object.
// assignment to undeclared variable bar
function Foo() { with (this) { bar = 42; } }

.... Come on, the whole point of that was to show that the `with' statement's
meaning is not always what you would expect using common sense. Had a
`bar' property been created before with

this.bar = 23;

we probably would not have had a need for the `with' statement in the
first place.


No, but that was exactly what the OP wanted to avoid, since the properties
were already created but needed the correct value assigned.

Using "with" is a problem because you can only safely use the guaranteed
properties of the parameter object inside the scope, and not any other
variable that could be in scope, because the parameter object might have
an unexpected property in some environments that would shadow the other
variables.

That, and some people are expecting it to do things it doesn't.

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
May 26 '06 #13
Lasse Reichstein Nielsen wrote:
Thomas 'PointedEars' Lahn <Po*********@web.de> writes:
Lasse Reichstein Nielsen wrote:
Thomas 'PointedEars' Lahn <Po*********@web.de> writes:
Lasse Reichstein Nielsen wrote:
> with(this) {
> scale = 30;
> mouseDown = 0;
> // ..
> }
>
> It will make properties of the "this" object appear as variables in
> the created scope.
No, it will not.
Yes, it will.

What it will not do is to make assignments to non-properties create
properties. The existing properties *will* work as variables in
the created scope, assignment and all.

var x = {foo:37};
with(x) {
foo = 42;
bar = "not";
}
alert([x.foo,bar]); // 42,"not"
You miss the point. It works with `x.foo' because `x' was declared in
that execution context and therefore becomes a property of the Variable
Object of that context;


The name "x" is irrelevant here, what matters is that "foo" is a property
of the object used as parameter of the "with" statement, and "bar" is not.

I repeat my initial statement:

"with(this){...}" will make properties of the "this" object appear as
variables in the created scope.

And it will. And it will do nothing else. It won't change the variable
object of the execution context, or any other property of variable
creation, so you don't get a new way of creating new properties of the
parameter object. You still have to do that with "this.newProperty=...".


I find your notion of "appear as variable" highly questionable. For
identifier resolution through the scope chain exists, and by that idea you
suggest to the reader that every reference that has a non-null base object
should be perceived as a variable, which is simply not the case.

Please also note that there is an important difference between "(to) seem"
and "(to) appear".
Reading a variable name that corresponds to a property of "someObject"
will read that property. [...]


And that is where we do not agree. There is a difference between a variable
and a property. I could accept "identifier", but not "variable name".
Your inability to recognize `bar' being created as a property of the
Global Object directly instead of the corresponding execution context's
Variable Object (provided that they are different) is reason enough to
demonstrate that the `with' statement should not be used at all.


Oh, I'm quite capable of recognizing it, although my explanation
apparently haven't shown that clearly enough.


Apparently. Maybe you should select your terms more carefully.
Come on, the whole point of that was to show that the `with' statement's
meaning is not always what you would expect using common sense. Had a
`bar' property been created before with

this.bar = 23;

we probably would not have had a need for the `with' statement in the
first place.


No, but that was exactly what the OP wanted to avoid, since the properties
were already created but needed the correct value assigned.

Using "with" is a problem because you can only safely use the guaranteed
properties of the parameter object inside the scope, and not any other
variable that could be in scope, because the parameter object might have
an unexpected property in some environments that would shadow the other
variables.

That, and some people are expecting it to do things it doesn't.


But you can _not_ expect the OP, especially not if he is new to the
languages, to understand this difference without proper explanation
(no offense meant). For a reasonable expectation (which I described
as "common sense") is that within a with-block _all_ identifiers
relate to the parameter expression as their base object, no matter
the circumstances. However, that is _not_ the case.
PointedEars
--
When the power of love overcomes the love
of power, the world will know peace.
-- Jimi Hendrix
May 26 '06 #14

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

Similar topics

11
by: Guotao Luan | last post by:
Hello All: I notice that there have been frequent questions being asked about template here so I guess it is okay to post this message here. I just wrote a c++ tempalte tutorial/review, I would...
4
by: binnyva | last post by:
Hello Everybody, I am writing an interactive tutorial for JavaScript. I created a text box into which the users can input javascript commands. On pressing a button, these commands will be...
7
by: Tim Johnson | last post by:
I'm an experienced programmer, but new to Javascript. For OOP: python and C++ backgrounds, among others I have one book on js - (Javascript Application Cookbook). I'd welcome further...
15
by: binnyva | last post by:
Hello Everyone, I have just compleated a JavaScript tutorial and publishing the draft(or the beta version, as I like to call it) for review. This is not open to public yet. The Tutorial is...
11
by: Alan Silver | last post by:
Hello, I am a seasoned Classic ASP programmer who is interested in learning ASP.NET. I bought a book (Que's Special Edition Using ASP.NET) which is complete rubbish, and would like a...
9
by: julie.siebel | last post by:
Hello all! As embarrassing as it is to admit this, I've been designing db driven websites using javascript and vbscript for about 6-7 years now, and I am *horrible* at form validation. To be...
2
by: Turbo | last post by:
Here is small javascript that i aggregated using various sources from web. Please comment if you find it useful. http://sandy007smarty.seo.iitm.ac.in/2006/09/26/javascript-tutorial/
2
by: Bundy | last post by:
Hi On my webpages I have replaced the submit button with a rolling submit button using the script below (Script 1). This script is used by many of my webpages and is included in a external...
3
by: Randy Smith | last post by:
Hi, It appears as though we will have a new coding standard for field validation that includes "IsPageValid". I've been unable to find anything about this on the "microsoft.com" site by googling...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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...
0
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,...
0
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...
0
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...
0
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,...

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.