JavaScriptKatie Fowle
Programming Languages
Dr. Lyle
October 27, 2011
The Development of JavaScript
Background
In the 1990s the internet had become a widely used entity and a fixture in many
people's lives. For that reason, there was enormous potential for capabilities beyond just static
web pages, but there was no good, standardized way to accomplish this. Developers needed a
way to receive and process data from web pages, display pop-ups, process requests, and
perform a huge variety of other functions.
JavaScript was developed mainly by Brendan Eich at Netscape in 1995. It was originally
known as Mocha, then Livewire, then LiveScript. However, at the time Java was enjoying a lot
of attention and success so the name JavaScript was soon adopted. The main goal for the
project was to develop a language that Netscape's browser, Navigator, could use to add
interactivity to web pages. About.com tells us that one of the major advantages of JavaScript is
that "... it was integrated into the browser (meaning that the browser would interpret the
commands directly without requiring the code to be compiled and without requiring a plugin to
be able to run it)." (http://javascript.about.com/od/reference/a/history.htm) JavaScript was
loosely typed and had relatively low barriers to entry. It could be added to any existing html
with no need of a compiler so no sophisticated IDE's or debuggers were created for
development with the language. For this reason, some programmers wrote off the language at
first or treated it as a beginner's language. This slowed it's spread at first, but JavaScript's critics
were still not able to keep the language down and it soon rose to be an industry standard.
The Language
JavaScript is a scripting language that is used today to add interactivity to web pages and
to allow dynamic content on web pages. It is an industry standard language and is used by a
large number of developers. The language is interpreted and each function is translated only
when it is called, in order to allow faster load times for web pages. Also, it is a single thread
language, so concurrency is not possible through straightforward avenues.
JavaScript is considered to be "weakly typed" because there are very few restrictions -
alarmingly few some would say - on what is allowed and what is not. Because of the lack of
rules, many people who use the language regularly and have published any material on the
subject have developed their own techniques and "rules" that they impose upon their code to
maintain some readability. This varies depending on the place one looks for information, but
the general consensus is that some form of regulation is a must in writing quality and easily
maintainable code. This allowance for people to create their own styles makes learning the
language somewhat more difficult, but perhaps makes regular use of the language a more
personalized experience.
Including JavaScript in Web Pages
There are a few ways to infuse JavaScript code into a web page. The first, and most
straightforward way is by inserting the code straight into the HTML document. The actual
script is written between the html tags <script type="text/javascript> </script> and this block
can be placed either between the <head> </head> tags, <body> </body> tags, or both. An
HTML document can have as many scripts as the user desires. If the script consists only of lines
of commands, the script will be interpreted and executed when the page loads. This is not
always the goal, however. In order to execute a script only in response to an event the script
must be a function and be called by and object on the page, such as the following:
<html><head><script type="text/javascript">
function displayDate(){
document.getElementById("demo").innerHTML=Date();}
</script></head>
<body>
<button type="button" onclick="displayDate()">Date</button>
</body></html>
(w3schools.com)
This sort of use is very common and will be describe in further detail shortly.
Another way to include scripts is to write them in separate document and include them
in the html page in the following format:
<script type="text/javascript" src="xxx.js"></script>
This technique is common when a script is going to be used over and over on multiple pages.
Scripts can be written in Notepad++ or an IDE (although those are not as prevalent for
JavaScript) and is saved with a .js extension. When scripts are written in an outside file, the
<script> </script> tags are not included in the .js file.
Data Types
JavaScript makes extensive use of Objects as data types. This emphasis on Objects gives
rise to the perception that it contains only Objects as data types, but this is not true. There are
three primitive types: numeric, string, and boolean. Aside from these three types,
programmers have several built in objects they can use or they can build their own objects. The
built in objects are used as constructors (with one exception) through which, programmers can
store data and create more complex objects. The built in objects are Date, Array, Math,
Function, RegExp, String, Number, and Boolean.
Clearly, these last three resemble JavaScript's primitive types closely. These objects are
different than their primitive counterparts in that the objects each have a constructor and their
own set of methods and properties, while the primitive types contain only the raw data
assigned to them. A variable of a primitive type can, however call a method of the
corresponding object. In this case, a shell or "container" object would be created around the
primitive type, the called upon method would execute, and the container object would then be
discarded. It is this ability to treat even primitive types as objects that has given rise to the
myth that all JavaScript types are objects. One must see, however, that this is not in fact the
case.
The Math object works differently than the rest. Cody Lindly in JavaScript
Enlightenment says, "[Math] is a static object, rather than a constructor function, meaning you
canʼt do this: var x = new Math(). But you can use it as if it has already been instantiated (e.g.
Math.PI). Truly, Math is a just an object namespace set up by JavaScript to house math
functions." (Lindly,pg. 22)
Primitive Types
Primitive variable names are case sensitive, must begin with a letter or underscore and
are declared as follows:
var foo;
It is not required that variables be declared before use and any variables not declared using the
var keyword are automatically global variables. In general, variables declared inside functions
are local to that function and those declared outside the function are global. Variable types are
implicitly declared and do not have to remain the same type throughout the program. So foo
may be assign "bar" then 5 then true at any given time. It is suggested, however, in order to aid
readability that a variable be used for only one type throughout the program. Since this
flexibility exists, type binding is dynamic.
Objects
Object names are also case sensitive and must begin with a letter or underscore. A
generic object can be declared and filled as follows:
var truck = new Object();truck.make = "Ford";
truck.mpg = 20;
truck.isNew = false;
These statements declare truck to be an object, create properties make, mpg, and isNew, and
assign values to each individually. With this method, the built in Object() constructor is called
and the truck object is filled in the subsequent statements.
One may also create custom objects that do not call the Object() constructor and are
not Object() objects. For this sort of structure, a custom constructor must be specified using
the following format:
var Car = function(make, mpg, isNew){this.make = make;
this.mpg = mpg;
this.isNew = isNew; }
var truck= new Car(Ford, 20, false);
The generic object Car has a constructor function that truck calls upon when it is initialized. It is
with this sort of structure that JavaScript implements some object orientation. In the preceding
example, the Car object is like a generic class and truck is like an instantiation of that class.
Functions v. Methods
A reasonably simple, but important concept to grasp is that JavaScript does not
recognize a difference between methods and functions. As a programmer, one can write
functions in such a way as to simulate methods and functions, but ultimately they are the same.
For instance, in the previous example Car is an object with a constructor function as previously
discussed. This can be determined partly by the fact that one see's variables written as
"this.make", etc. The "this" keywords suggests Car is an object with the respective properties
associated with it. Objects can also be defined using literal notation, which looks like the
following example:
var obj = {prop1: "hello"
prop2: 3
prop3: [1,2,3]
method1: function(){ return this.prop2*4 }};
In this notation, obj is not a generic object that needs to be instantiated, so this is another way
to define specific objects. The point being made with this code snippet however, is that one
can create specific functions for specific objects that will perform as functions would in Java.
Method1 may be called as follows:
obj.method1(); //returns 12
There are also a few ways to create functions that are not associated with a specific
object. A function can be created generically and then have multiple instances like in the case:
var funct = function(message) {alert(message); };var instanceoffunct = new funct("hello world");
In this example, multiple instances of funct could be created so that there could be several
functions performing the same general task with different parameters. This can be a useful
ability at times, but it can be a strange concept to some programmers, cutting down on some
readability.
Another format for declaring and using functions was shown earlier, but not really
explained. The example function looked like the following:
function displayDate(){
document.getElementById("demo").innerHTML=Date();}
This format looks more familiar to C-style programmers than the previous examples have and
indeed, this form does operate very similarly to functions in Java. The function can be called by
name (displayDate()) later within the script or in the HTML as was illustrated previously. Since
this is the more intuitive form for many programmers, this sort of use of functions is very
common.
A final way to declare a function is one of the least common ways, and is not
recommended by most experienced JavaScript programmers. As discussed earlier, JavaScript
has several built in objects with constructor functions attached. One of these such objects is
the Function() object. This object is a constructor through which, functions can be created
using the following format:
var AddFun = new Function('num1', 'num2', 'return num1+num2');
AddFun(2,2); //returns 4
As with other built in constructors, Function() must be used in conjunction with the new key
word. When Function() is called, all of the parameters must be strings. The first strings are the
arguments that will be passed to the function being created, and the last string is the body of
the function itself (this is not limited to a return statement, but can be as lengthy as the
programmer wants it to be). Cody Lindy says of this technique of creating functions, " Directly
leveraging the Function() constructor is not recommended or typically ever done because
JavaScript will use eval() to parse the string containing the functionʼs logic. Many consider eval()
to be unnecessary overhead. If itʼs in use, a flaw in the design of the code is highly possible."
(Lindly, pg. 64) It is for this reason that this technique is brought up, but will not be further
explored here.
Expressions and Assignment
Arithmetic Expressions
Arithmetic for primitive numerical types is the same as Java. The standard use of +-*/%
for addition, subtraction, multiplication, division, and modulus respectively, all apply. In
addition, the ++ and -- can be used to add or subtract 1 from a numerical value as in Java.
Since types in JavaScript are implicit anyway, one does not run in to the issue of having to
explicitly promote types. If one needs to add a floating point value and an integer value, the
integer will simply be promoted implicitly and the operation will be performed. One thing to
note, however, is that the “+” sign is also used for string concatenation. In this case,
JavaScript’s implicit type conversion can trip things up if not used correctly. In the statement,
“5” + 5, the integer 5 is converted to a string and the two are concatenated, returning “55.”
This conversion is not always intuitive, so it is good to be aware of it. Types may be explicitly
converted using the parseFloat() and parseInt() or the .toString() function of the Number object.
A more complete list of operators can be found in the appendix.
Assignment Statements
Assignment statements in JavaScript are not very different than those of Java for
primitive types and are straightforward so they will not be explained in detail here. A complete
list is included in the appendix. The major difference from C-based languages is that any data
type can be assigned to any variable, since type declaration is implicit. Variables that previously
held numerical values can be assigned to a string without any errors.
When dealing with object assignments, the major thing to note is that objects are
copied by reference, not by value. Therefore, if there is an object ObjA and you assign ObjB =
ObjA, ObjB does not get a copy of ObjA’s properties. The address of ObjA’s properties is copied
to ObjB. If any property is changed either through an operation on ObjA or ObjB, the contents
of the other will obviously be changed as well.
Comparisons
Comparison expressions for primitive types are also somewhat similar to Java’s
expressions with a few differences. For one, when comparing a string value and number value,
the types are coerced for the sake of comparison, so “5”==5 returns true. However, there is
another operator, “===”, that does not coerce types so “5”===5 returns false. There are
corresponding "!=” and “!==” operators that use the same principles. The others are
straightforward and included in the appendix.
When comparing objects, two objects are equal only if they reference the same object.
Consider the code:
var objectFoo = {same: 'same'};
var objectBar = {same: 'same'};
console.log(objectFoo === objectBar); // logs false
(Lindly, pg. 34)
It does not matter that the two objects are of the same type and contain the same elements;
they are not the same object so they are not equal.
Control Structures
As with most of the previous topics, JavaScript’s control structures are very similar to
Java’s in syntax and functionality. There are if..else and switch statements as well as a ternary
operator that work as the Java counterpart’s do as selection statements. Also, iteration tools
include for, for..in, while, and do..while that are again the same concept as those in Java. A
final structure that is more unique is the with statement. A line of code that looks like
x = Math.round( Math.LN2 + Math.E + Math.pow( y, 4 ) );
can be written as
with( Math ) {
x = round( LN2 + E + pow( y, 4 ) );
}
(http://www.howtocreate.co.uk/tutorials/javascript/controls)
Whether this statement clarifies or complicates the code can be debated, but nonetheless the
potential is worth mentioning.
Event and Exception Handling
Event handling is the lifeblood of JavaScript, as it is an important function of the
language. The elements required for event handling have been discussed throughout this
paper so here we will simply put the pieces together. JavaScript has several major events it
recognizes. These events can be placed in HTML tags and a function, like those described
previously, will be indicated to run upon the occurrence of the event. Some of the recognized
events include onclick, onload, onmouseover, etc. An example of the use of onclick has been
provided earlier in the paper.
JavaScript also provides a way to handle exceptions through try..catch..finally blocks.
These are the same syntactically and semantically as Java. This structure is not recognized by
Internet Explorer 4 and a few other lesser known browsers, however so care should be taken
when using it.
Language Evaluation
There is no such thing as a general consensus with JavaScript. Often, the capabilities
that one programmer cites as a strong suit of the language, another will cite as a short coming.
This is due mostly to the weak typing of the language.
The language is very flexible about how one can write their code. There is almost never
one way to do something. For this reason, code is not very readable. There are some
constructs that are very intuitive and easy to understand and these elements are certainly
readable. However, since there are often other ways to write the same code, one cannot rely
on anything being done in a uniform or predictable fashion. Also, there are some constructs
that are not at all intuitive or readable. Finally, it would be somewhat difficult to follow
someone else’s code if it was even slightly complicated; since so many things are permitted, it is
hard to follow the logic of another person. People often have adopted their own styles, to an
extent; one programmer’s code may look vastly different from another’s even if they
accomplish the same task.
Due to this flexibility and weak tying however, the programmer gains some writability.
Since programmers create some of their own guideline’s and rules, they may write with more
freedom and may therefore find it much easier. JavaScript is very powerful and a lot can be
done in a few lines. However, the multitude of ways to perform a task can lessen writablity for
beginners of the language.
JavaScript suffers some with reliability also. For one, there is no type checking and
values are implicitly converted and coerced to perform functions. This can cause logic errors
that are hard to find if the programmer is not intimately familiar with how JavaScript promotes
and coerces types. Also, since variables do not even need to be explicitly declared, a
programmer could easily misspell a variable name and a separate variable would be created,
rather than an error occurring and quickly pointing out the problem. As stated before, many
avid JavaScript programmers have developed their own rules for themselves to supplement the
lack there of, but programmers cannot be expected to keep these perfectly without a compiler
to check them nor can they even be trusted to set these rules for themselves. For this reason,
JavaScript has some shortcomings in reliability.
Cost
Readability and writability are the major factors when assessing cost. Based on the
previous discussion of these two factors, we can more specifically assess elements that
determine cost. The cost of program development can be somewhat high. If a programmer
needs only to do a few simple tasks such as display a picture or text in the event that a button is
clicked, then learning to do that only requires a few minutes online. However, if a developer
desires to be an expert in the language, it could take more time and study. For one, it is
important to find one really good source to learn the fundamentals. If one tries to learn
through several sources, it can be very confusing since there are so many ways to do things.
Also, after one has learned the fundamentals, there is still plenty of time and research required
before one can know the extent of JavaScript’s capabilities. Even once one knows and can
perform basic tasks there is still a huge amount to learn before one can be considered an
expert.
The maintainability of the code is a function of its readability which is not a strong suit in
general. Most tasks performed by JavaScript can be written in a readable fashion, but often
they can also be somewhat convoluted. For this reason JavaScript can be relatively
maintainable but one cannot rely on it to be so. If a programmer is disciplined and writes
things with the specific intention of readability and maintainability than it is possible to
accomplish these things, but only when one makes a concerted effort. Without much effort,
however code can be scrambled and hard to maintain.
These factors, along with JavaScript’s reliability issues assessed earlier, make it strong,
but without its flaws. JavaScript can be effective and maintainable, but this requires a cost for
the programmer who must be particularly diligent to accomplish this. On the other hand, the
programmer could be sloppy and use shortcuts lowering the time and cost to him, but also
greatly lowering the maintainability and reliability, raising the overall cost of development. As
one can see determining the cost of JavaScript is not a trivial exercise, but one can safely see
that there are certainly some costs that balance out the benefits.
Appendix
Table 3.1 Assignment operators
Shorthand operator Meaning
x += y x = x + y
x -= y x = x - y
x *= y x = x * y
x /= y x = x / y
x %= y x = x % y
x <<= y x = x << y
x >>= y x = x >> y
x >>>= y x = x >>> y
x &= y x = x & y
x ^= y x = x ^ y
x |= y x = x | y
(https://developer.mozilla.org/en/JavaScript/Guide/Expressions_and_Operators#Operators)
var var1 = 3, var2 = 4;
Table 3.2 Comparison operators
Operator Description Examples returning true
Equal (==) Returns true if the operands are equal. 3 == var1
"3" == var1
3 == '3'
Not equal (!=) Returns true if the operands are not equal. var1 != 4var2 != "3"
Strict equal (===) Returns true if the operands are equal and of the same type.
3 === var1
Strict not equal (!==)
Returns true if the operands are not equal and/or not of the same type.
var1 !== "3"3 !== '3'
Greater than (>) Returns true if the left operand is greater than the right operand.
var2 > var1"12" > 2
Greater than or equal (>=)
Returns true if the left operand is greater than or equal to the right operand.
var2 >= var1var1 >= 3
Less than (<) Returns true if the left operand is less than the right operand.
var1 < var2"12" < "2"
Less than or equal (<=)
Returns true if the left operand is less than or equal to the right operand.
var1 <= var2var2 <= 5
(https://developer.mozilla.org/en/JavaScript/Guide/Expressions_and_Operators#Operators)
Table 3.4 Bitwise operators
Operator Usage Description
Bitwise AND a & b Returns a one in each bit position for which the corresponding bits of both operands are ones.
Bitwise OR a | b Returns a one in each bit position for which the corresponding bits of either or both operands are ones.
Bitwise XOR a ^ b Returns a one in each bit position for which the corresponding bits of either but not both operands are ones.
Bitwise NOT ~ a Inverts the bits of its operand.
Left shift a << b Shifts a in binary representation b bits to the left, shifting in zeros from the right.
Sign-propagating right shift
a >> b Shifts a in binary representation b bits to the right, discarding bits shifted off.
Zero-fill right shift a >>> b Shifts a in binary representation b bits to the right, discarding bits shifted off, and shifting in zeros from the left.
(https://developer.mozilla.org/en/JavaScript/Guide/Expressions_and_Operators#Operators)
Works CitedControl Structures. (2011, March). Retrieved October 2011, from JavaScript Tutorials: http://www.howtocreate.co.uk/tutorials/javascript/controls
Expressions and Operators. (2011, July). Retrieved October 2011, from MDN: https://developer.mozilla.org/en/JavaScript/Guide/Expressions_and_Operators#Operators
JavaScript Tutorial. (1999-2011). Retrieved October 2011, from W3Schools: http://www.w3schools.com/js/default.asp
JavaScript Tutorials. (1997-2011). Retrieved October 2011, from JavaScript Kit: http://www.javascriptkit.com/javatutors/oopjs.shtml
Lindley, C. (First Edition). JavaScript Enlightenment.
Top Related