[Previous] [Next] [First] [Last]


Types, Values, and Variables

3.1 Types

There are two kinds of types in JavaScript: primitive types and reference types. There are, correspondingly, two kinds of data values that can be stored in variables, passed as arguments, returned by methods, and operated on: primitive values and reference values.

Type:

          PrimitiveType
          ReferenceType

JavaScript's primitive data types are boolean, number, and undefined; its reference types are string, object (including the null object), and function. Strings compare by value (ASCII lexicographical order), not reference, when used as operands of the equality and relational operators.

The boolean type has the truth values true and false. A number can be either an integer or floating-point; JavaScript does not explicitly distinguish between them. The integer bitwise-logical and shift operators work with 32-bit signed two's-complement integers. Floating-point numbers are in 64-bit IEEE 754 format.

An object in JavaScript is a container that associates names and indexes with data of arbitrary type. These associations are called properties. Properties with function values are called the object's methods.

Each type has a corresponding object class: Boolean, Number, String, Object, and Function. JavaScript converts values to objects by constructing an object of the corresponding class for the value's type.

3.1.1 Type Names

The typeof operator returns a string naming the type of its operand, as described in 4.5.10 The typeof operator.

3.1.2 Type Conversion

As summarized in Table 3.1, JavaScript performs automatic type conversion at runtime. The From type of an operand is its type after evaluation. The To type is the type required by its combination with another operand and a binary operator, or by a unary operator.

To type
function object number boolean string
undefined error null error false "undefined"
function N/C Function object valueOf/error valueOf/true decompile
object
(not null)
(null)

Function object
error

N/C

valueOf/error
0

valueOf/true
false

toString/valueOf1
"null"
From type number
(zero)
(nonzero)
(NaN)
(+Infinity)
(-Infinity)

error
error
error
error
error

Number
Number
Number
Number
Number

N/C

false
true
false2
true
true

"0"
default*
"NaN"
"+Infinity"
"-Infinity"
Boolean
(false)
(true)

error
error

Boolean
Boolean

0
1

N/C

"false"
"true"
string
(empty)
(non-empty)

error
error

String
String

error
number/error

false
true

N/C

Key

When two results separated by a slash are given, JavaScript tries the first, and if unsuccessful, uses the second.

N/C: No conversion necessary.
decompile: A string containing the function's canonical source.
toString: The result of calling the toString method.
valueOf: The result of calling the valueOf method, if it returns a value of the To type.
number: Numeric value if string is a valid integer or floating-point literal.

3.1.3 The toString method

Every object has a toString method used to convert the object to a string value, as follows:

Examples

For example,

function f() {
          return 42
}

function Car(make, model, year) {
          this.make = make
          this.model = model
          this.year = year
}

objnull = null

o = new Car("Ford", "Mustang", 1969)
posInfinity = 10*1e308
n0 = 0
n1 = 123

println(true.toString())
println(false.toString())
println(f.toString())
println(objnull)
println(Math.toString)
println(o.toString())
println(n0.toString())
println(n1.toString())
println(posInfinity.toString())

This script returns the following:

true
false
function f() { 
    return 42;
} 
null
function toString() {
    [native code]
} 
[object Object]
0
123
Infinity

3.1.4 The valueOf Method

Every object has a valueOf method that returns the value associated with the object, if any. For Boolean and Number objects, valueOf returns the primitive boolean or number value passed to the object's constructor. For String and Function objects, valueOf returns the string or function reference that was passed to the constructor. If an object has no associated value, valueOf returns the object reference itself.

3.2 Primitive Types and Values

A primitive type is predefined by the JavaScript language:

PrimitiveType:
          boolean
          number
          undefined

3.2.1 Boolean Types and Values

The boolean type represents a logical quantity with two possible values, true and false.

3.2.2 Boolean Operations

JavaScript's Boolean operators treat their operands as boolean values. The logical-not operator returns a boolean result; the remaining operators return one of their operands as their result, with no conversion of the result to boolean.

JavaScript's Boolean operations are:

3.2.3 Numeric Types and Values

JavaScript numbers are signed 64-bit IEEE 754 floating-point values, as specified in IEEE Standard for Binary Floating-Point Arithmetic, ANSI/IEEE Standard 754-1985 (IEEE, New York).

The IEEE 754 standard includes not only positive and negative sign-magnitude numbers, but also positive and negative infinities, and a special Not-a-Number (hereafter abbreviated NaN) value. The NaN value is used to represent the result of certain operations such as dividing zero by zero.

The largest positive finite number is 1.79769313486231570e+308. The smallest positive finite nonzero number is 4.94065645841246544e-324.

Except for NaN, numeric values are ordered; arranged from smallest to largest, they are negative infinity, negative finite values, negative zero, positive zero, positive finite values, and positive infinity.

NaN is unordered, so the numerical comparison operators <, <=, >, and >= return false if either or both of their operands are NaN . The numerical equality operator == returns false if either operand is NaN, and the inequality operator != returns true if either operand is NaN . In particular, x==x is false if and only if x is NaN, and (x<y)==!(x>=y) will be false if x or y is NaN.

3.2.4 Numeric Operations

JavaScript provides a number of operators that act on numeric values:

Numeric operators behave as specified by IEEE 754. In particular, JavaScript requires support of IEEE 754 denormalized floating-point numbers and gradual underflow, which make it easier to prove desirable properties of particular numerical algorithms.

JavaScript requires that floating-point arithmetic behave as if every floating-point operator rounded its floating-point result to the result precision. Inexact results must be rounded to the representable value nearest to the infinitely precise result; if the two nearest representable values are equally near, the one with its least significant bit zero is chosen. This is the IEEE 754 standard's default rounding mode known as round to nearest.

An operation that overflows produces a signed infinity, an operation that underflows produces zero, and an operation that has no mathematically definite result produces NaN. All numeric operations with NaN as an operand produce NaN as a result. Since NaN is unordered, a numeric comparison operation involving one or two NaNs returns false and any != comparison involving NaN returns true, including x!=x when x is NaN.

The following example illustrates:

// an example of overflow:
d = 1e308
println("overflow produces infinity: ")
println(d + "*10==" + d*10)
println("")

// an example of gradual underflow:
d = 1e-305 * Math.PI
println("gradual underflow: ")
println(d)
for (i = 0; i < 4; i++)
          println(d /= 100000)
println("")

// an example of NaN:
d = 0.0/0.0
println("0.0/0.0 is Not-a-Number: ", d)
println("")

// an example of inexact results and rounding:
println("inexact results with floating point arithmetic:")
for (i = 0; i < 100; i++) {
          z = 1.0/i
          if (z*i != 1.0)
                    println(i)
}

This example produces the following output:

overflow produces infinity: 
1e308*10==Infinity

gradual underflow: 
3.141592653589793e-305
3.1415926535898e-310
3.141592653e-315
3.142e-320
0

0.0/0.0 is Not-a-Number: NaN

inexact results with floating point arithmetic:
49
98

This example demonstrates, among other things, that gradual underflow can result in a gradual loss of precision. Note that when i is zero, z is NaN, and z*i is NaN.

3.2.4.1 Bitwise integer operations

The bitwise operators treat their operands as signed 32-bit integer values:

JavaScript uses round toward zero when converting a floating-point value to an integer, which acts, in this case, as though the number were truncated, discarding the mantissa bits. Round toward zero chooses the value closest to and no greater in magnitude than the infinitely precise result.

3.2.5 The Undefined Type

Any variable that has not been assigned a value is of type undefined. The undefined type has one value, undefined. The void operator evaluates its operand, discards the value, and results in undefined.

3.3 Reference Types and Values

JavaScript's reference types are objects, strings, and functions.

ReferenceType
          String
          Object
          Function

3.3.1 String Types and Operations

A string is a sequence of ASCII characters created by use of a string literal or a string expression.1 Every string has a length property that is an integer equal to the number of characters in the string. A string converts to a String object that has a number of built-in methods, described in 7.7 String Object.

The following operators are defined for strings:

Note the reference-type behavior for assignment operations, but not for equality and relational operations.

3.3.2 Object Types and Operations

An object is a container for properties. A value of type object is a pointer to such a container, or a special null reference, which refers to no object. Each property of an object can be of any type and can be named by any string. A property name that is a nonnegative integer literal is called an index. A property name that is an identifier (as defined in ) can be used after the dot operator (.).

The object operators are:

3.3.2.1 The Null Object

The null object is a special object that references no object. It is named by the null literal.

3.3.3 Function Types

A function is created by a function definition. The syntax for a function definition is given in 6.4.10 Function Definition Statement.

It is also possible to create a function object with the new operator as follows:

functionObject:
          identifierName = new Function("Block")
          identifierName = new Function(parameterList, "block")

parameterList:
          "identifierName"
          "identifierName", parameterList

where Block is the set of statements that defines the body of the function.

A function object is of type object not function. The only way to create a value of type function is with a function definition.

Examples

Here is a standard definition of a simple factorial function:

function fact(n) {
          if (n <= 1)
                    return 1
          return n * fact(n-1)
}

Here is the same function defined as a function object:

fact = new Function("n", "if (n <= 1) return 1; return n * fact(n-1);")

3.4 Variables

A variable is a storage location for a value and has an associated type, determined at run-time. A variable's value is changed by assignment or by the ++ (increment) or -- (decrement) operators.

3.4.1 Variable Lifetime

JavaScript has four kinds of variables, distinguished by lifetime:

3.4.2 Initial Values of Variables

Every variable in a JavaScript program has a value:

3.5 Names

A name is an identifier used to refer to an variable or a function in a JavaScript program. There are two forms of names: simple names and qualified names. A simple name is a single identifier. A qualified name consists of a name, a "." token, and an identifier; it is used when a name is associated with an object.

3.5.1 Scope Resolution

All names have scope. The name space in which functions are defined is called the global scope. Qualified names identify the scope explicitly as an object reference to the left of the dot operator. Simple names have implicit scope determined at run-time as follows:

3.5.2 Declaration and Visibility

JavaScript variables may be implicitly declared by assignment, or explicitly declared by a var statement. For example, both of the following statements declare the variable x if it has not been declared yet:

x = 42
var x

The second statement declares x but does not initialize it. Uninitialized variables have the value undefined. A var statement can initialize the variable it declares with an expression, called an initializer:

var x = 42

Implicit declarations take effect at runtime, in the normal order of execution. Explicit declarations have at most two effects, one at compile-time that defines a property of the variable's enclosing scope, and (if there is an initializer) a runtime effect that initializes the variable to the value of its initializer. A variable is visible once its implicit declaration has been executed, or its explicit declaration has been compiled.

A variable declared outside a function is a global variable, and once visible, is accessible everywhere in the global scope. A variable implicitly declared within a function is also a global variable. A variable declared with var within a function is a local variable, and is accessible only within that function.

3.5.3 Hiding Names

When there is a global variable with the same name as a local variable, the local variable is said to hide the global variable within the function. In this case, there are two variables, a global variable and a local variable, with the same names. Within the function, the local variable is used; everywhere else, the global variable takes precedence.

For example, in the function foo, x has a value of 17, but outside the function, it has a value of 42.

x = 42

function foo() {
          var x = 17
          println(x)
}

foo()
println(x)

The result of these statements is:

17
42


Footnotes

1 JavaScript 1.1 as implemented in Navigator 3.0 disallows the ASCII NUL character in strings.

2 In JavaScript 1.1 as implemented in Navigator 3.0, indexed properties default to null.


[Previous] [Next] [First] [Last]