lawrence said:
I'm learning Javascript. I downloaded a script for study.
Learning by studying other people's scripts is not a bad idea, but it
will be more productive in the long run if you can avoid studying poor
scripts. There are a number of tell-tale characteristics that can be
used to identify poor scripts, because they indicate that the script
author does not understand Javascript and/or HTML. The script you have
posted features most of them (as I will indicate below).
Please tell me how the variable "loop" can have scope in
the first function when it is altered in the second
function?
The variable - loop - is never declared (with the - var - keyword) and
as a result, when it is first created by an assignment of a value to the
identifier, it becomes a property of the global object and thus is
equivalent to a global variable.
It is not defined in global space, therefore
it is not a global variable, yes?
No.
Even if it was global,
how would it get from one function to another?
Global variables become named properties of the global object, and the
global object is the last object on the scope chain of every function
(and its execution context). Identifier resolution is carried out
against the scope chain of the current execution contexts so all
functions will resolve identifier that correspond with named properties
of the global object as references to the properties of that object
unless another object higher in the scope chain has a property with the
same name.
In PHP
variables are copied by value. Are they copied by
reference in Javascript?
Where any (ECMAScript) Object is concerned a variable will represent a
reference to that Object. Whether a variable that is assigned a
primitive value actually holds that value as such, or a reference to an
independent structure that holds the value, is unspecified and
unimportant.
<SCRIPT LANGUAGE="JavaScript">
To create valid HTML 4 a script element is required to have a TYPE
attribute. The type attribute renders the LANGUAGE attribute redundant
(and the Language attribute is officially deprecated and cannot be used
with the strict DTD). Competent authors of scripts for HTML web browsers
should be expected to possess a technical understanding of HTML which
will include an awareness of the requirements for valid mark-up.
<!-- Original: Eddie Traversa (
[email protected]) -->
The ECMAScript specification defines two types of comment, a multi-line
comment indicated by being surrounded with - /* - and - */ -, and an
end-of-line comment indicated by starting with - // - and continuing to
the end of the current line of source code. A competent javascript
author should be expected to be using javascript style comments within
javascript source code.
<!-- Web Site:
http://nirvana.media3.net -->
<!-- This script and many more are available free online at -->
<!-- The JavaScript Source!!
http://javascript.internet.com -->
<!-- Begin
HTML style comments used to "hide scripts from older browsers" are no
longer needed as those 'older' browsers are two generations older than
the oldest browsers currently in use. Anyone using such a construct to
hid code from web browsers is either not up to date (by a long way), or
operating on the basis of an old wives' tale, neither of which should be
seen as an indicator of competence.
function verScroll(dir, spd, loop) {
loop = true;
Assigning a value to an undeclared identifier will result in a
correspondingly named property being created on the global object and
the value assigned to that property. Thus this assignment does create a
global variable.
Good code authoring style would suggest that if a variable is to be
global it should be explicitly declared as a global variable using the -
var - keyword in the global scope. Doing so avoids ambiguity and
prevents variables that are intended to be global from looking like an
authoring mistake.
direction = "up";
speed = 10;
scrolltimer = null;
if (document.layers) {
var page = eval(document.contentLayer);
} else {
if (document.getElementById) {
var page= eval("document.getElementById('contentLayer').style");
} else {
if (document.all) {
var page = eval(document.all.contentLayer.style);
<snip>
The use of the - eval - function is the most tell-tale indicator of an
incompetent javascript author. If - eval - is used to evaluate a
constructed dot-notation property accessor as a string, where a variable
is used to provide a single identifier in that property accessor, then
the - eval - use can be directly replaced with a bracket notation
property accessor and be 2 to 40 times more efficient and supported in
more web browser. Thus a competent javascript author will never eval a
dot-notation property acessor string.
However, in this case there is no variable part to the property accessor
string being used in the second branch of the if/else construct, and the
first and third branches are not even acting upon strings. When the
argument to - eval - is not a string the function just returns the value
of that argument. The author of this code is not only incompetent enough
to be using eval to resolve property accessors, but also does not
understand what eval does or how it works. This is programming by
mystical incantation.
The above construct can be replaced with:-
var page = null;
if(document.layers){
page = document.layers['contentLayer'];
}else if (document.getElementById){
page= document.getElementById('contentLayer').style;
}else if (document.all){
page = document.all.contentLayer.style;
}
- where the main practical difference is that the - eval - function is
just omitted.
The other difference being the change from - document.contentLayer -
to - document.layers['contentLayer'] - in the first branch. This is done
to correct the irrational logic in the original where a test for the
existence of the - document.layes - collection is followed by the
assumption that if the collection exists then the required layers will
also be a property of the - document -. This assumption is termed
'object inference' and is not valid. Having verified that the layers
collection exists on the current browser the only means of accessing the
layer that can be validly inferred from the test is through the -
document.layers - collection.
However, the code is still not really correct as it assumes that the
element reference retrieval will be successful, and that in the latter
two branches the retrieved element will possess a - style - property. It
would be better to split these two actions up into an initial attempt to
retreave the element reference (by whichever means is supported),
followed by verifiecation of the success of that action, and then
normalisaiton to the style object with code such as:-
var page = getElementWithId('contentLayer');//a function
//that uses layers,
//gEID or document.all
if(page){
page = page.style||page;
... // Assign style properties.
}
The only common indicator of poor javascript authoring missing from this
script is browser detection based on the properties of the - navigator -
object.
Richard.