`

javascript 学习

 
阅读更多

character set:
Unicode character set(7-bit ASCII, 8-bit ISO Latin-1 encodings are subset of Unicode.)
Case sensitivity:
A case sensitivity language.(html is not case sensitivity.)
Whitespace and line breaks:
Js ignores spaces, tabs, new lines that appear between tokens.
Optional semicolons:
If your coding style is the same as java, then this rule can be ignored.
Comments:
Like java, js supports both c++(//) and c-style(/* */) comments.
Literals:
A literal is a data value that appears directly in a program. Following are all types of literals in js:
12 // The number twelve
1.2 // The number one point two
"hello world" // A string of text
'Hi' // Another string
true // A Boolean value
false // The other Boolean value
/javascript/gi // A "regular expression" literal (for pattern matching)
null // Absence of an object
{ x:1, y:2 } // An object initializer
[1,2,3,4,5] // An array initializer
identifiers:
you can use the same identifier naming ruls as in java, though there are some extra rules which can be ignored.
Reserved words:
primitive datatypes:
numbers,
string,
boolean,
null,
undetified,
composite datatypes:
object type:
an object(a member of object type)represents a collection of values(primitive values, composite values).
An objects can represent an unordered collection of named values or an ordered collection of named values. The latter one is called an array.
Objects and array are the same datatype fundamentally, but they behave differently and will usually be considered distinct types.
Another special kind of object is function. A function is an object that has executable code. A function has special behavior from other kind objects. Js defines a special syntax for function.
A few other kind of objectsstill exist. These objects don’t represent new data types, but new classes of objects, such as Date, RegExp, Error.
In js, there is no distinction between integer and floating-point values. All numbers are represented as floating-point values using 64-bit floating-point format by IEEE754.
Number literal: a number that appears directly in js.
integer literals:
you can exactly represent integers between -9007199254740992 (-253) and 9007199254740992 (253), inclusive. Note that certain integer operations in js are performed on 32-bit integers, which range from -2147483648 (-231 ) to 2147483647 (231-1).
Hexadecimal and octal literals:
A hexadecimal literal begins with 0x or 0X.
Although the ECMAScript doesn’t support octal literals, some
implementations of javascript does. An octal literal begins with 0.
Floating-point literals:
Floating-point literals can have traditional syntax such as
3.1415926, and also can be represented using exponential notation such as 1.444E-32.
Note that there are infinitely real numbers, but only a finite
number of them can be represented exactly by the js floating-point format.
Working with numbers:
Arithmetic operators,
Mathematical functions,
Number conversions:
Numbers and strings can be interconverted .
Special numeric values:
Infinity,
NaN: not a number,
Number.MAX_VALUE,
Number.MIN_VALUE,
Number.NaN: not a number,
Number.POSITIVE_INFINITY,
Number.NEGATIVE_INFINITY,
a string is a sequence of Unicode letters, digits, punctuation characters, and so on.
A string is quoted by single or double quotation marks.
No char data type exists in js.
String literals:
Double-quote characters can be contained within strings delimited by single quotation marks, vice versa.
Escape sequences in string literals:
/ is the escape character.

Table 3-2. JavaScript escape sequences
Sequence
Character represented
/0
The NUL character (/u0000).
/b
Backspace (/u0008).
/t
Horizontal tab (/u0009).
/n
New line (/u000A).
/v
Vertical tab (/u000B).
/f
Form feed (/u000C).
/r
Carriage return (/u000D).
/"
Double quote (/u0022).
/'
Apostrophe or single quote (/u0027).
//
Backslash (/u005C).
/xXX
The Latin-1 character specified by the two hexadecimal digits XX.
/uXXXX
The Unicode character specified by the four hexadecimal digits XXXX.
/XXX
The Latin-1 character specified by the octal digits XXX, between 1 and 377. Not supported by ECMAScript v3; do not use this escape sequence.
Note that the blackslash escape (/) can’t be used before a line break to continue a string token across two line or to include a literal line break in a string.
If the blackslash precedes any characters that is not in the table above it will be ignored simply. For an instance, /# is the same as #.
Working with strings:
Concatenate strings by +:
Msg = “Hello, ” + “world!”;
Length of a string:
Msg.length;
More methods:
Msg.charAt( Msg.length -1 );
sub = s.substring(1,4);
i = s.indexOf('a');
more later.
Note that
last_char = s[s.length - 1];
is not part of ECMAScript v3 standard, is not portable, and should be avoided.
String is not a data type of object,
Though string properties and methods can be used as the same way as the object data type.
Conversion between numbers and strings:
l conversion-through-concatenation:
“a string”+100.
l String() function:
l toString(base) function:
primitive numbers are first convertedto Number object, then call the function above.
l toFixed(n)
display a number with specified digits (n) after the decimal point.
l toExponential(n)
specify a exponential number with one digit before the decimal point and n digits after the decimal point.
l toPrecision(n)
display a number using n digits of the primitive number.
Examples for above three:
var n = 123456.789;
n.toFixed(0); // "123457"
n.toFixed(2); // "123456.79"
n.toExponential(1); // "1.2e+5"
n.toExponential(3); // "1.235e+5"
n.toPrecision(4); // "1.235e+5"
n.toPrecision(7); // "123456.8"
l automatically conversion such as
var number = string_value – 0;
l Number():
Based 10 radix only works.
l parseInt(number):
l parsetInt(number, base):
l parseFloat():
if the three functions above fail they return NaN.
Boolean values can convert to and from other types and often automatically converted.
In a numeric context, true à 1 and false à 0.
In a string context, true à “true” and false à “false”.
When a boolean value needed a number ( 0 or NaN )à false, else the number à true. When a Boolean value needed en empty string à false, else à true. null and undefined value à false, and non-null object, array, function à true.
Explicit conversion:
Boolean()
Another technique:
var x_as_boolean = !!x;
An import feature of javascript which is different from other languages is that functions are values that can be manipulated by javascript code. That feature gives more flexibility.
Functions are values in js. It means that functions can be stored in variables, arrays and objects, and it means that functions can be passed as arguments(自变量,变量) to other functions. We can see details later.
Function literals:
Three ways of defining a function:
function square(x) { return x*x; }
var square = function(x) { return x*x; }
var square = new Function("x", "return x*x;");
An object is a collection of named values. The values are referred as properties.
Properties of objects are like javascript variables in many ways.
When a function value is stored in a property the function is called a method, such as document.write("this is a test");
Objects can serve as associative arrays. They can associate arbitrary data values with arbitrary strings. To use such objects, you should do it like this:
Image[“weight”],
Statement above can access a property value named weight.
Creating objects:
You can do it like :
var o = new Object( );
var now = new Date( );
var pattern = new RegExp("//sjava//s", "i");
then to use and set their properties:
var point = new Object( );
point.x = 2.3;
point.y = -1.2;
object literals:
an object literal syntax allows you to create an object and specify its properties, which is also called an object initiallizer.
You can implement an object initiallizer as following:
var point = { x:2.3, y:-1.2 };
nested object literals:
var rectangle = { upperLeft: { x: 2, y: 2 },
lowerRight: { x: 4, y: 4}
};
Note:
The properties in object literals can be arbitrary javascript expressions besides constants. Also, the property names may be strings rather than identifiers:
var square = { "upperLeft": { x:point.x, y:point.y },
'lowerRight': { x:(point.x + side), y:(point.y+side) }};
objects conversions:
non-null object à false,
object à object.toString(),
object à object.valueOf(),if return object, use toString() and
try to convert the string value to a number.
Object to primitive data type will discuss later.
an array is a collection of data values just as an object is. While each data value contained in an object has a name, they has an index in an array. The first index is 0.
The data value in an array do not need to be the same data type as javascript is an untyped language.
Creating arrays:
Method 1:
var a = new Array( );
a[0] = 1.2;
a[1] = "JavaScript";
a[2] = true;
a[3] = { x:1, y:3 };
method 2:
var a = new Array(1.2, "JavaScript", true, { x:1, y:3 });
method 3: create an array with 10 undefined elements,
var a = new Array(10);
array literals:
a literal syntax for creating and initializing arrays:
var a = [1.2, "JavaScript", true, { x:1, y:3 }];
nested array literals:
var matrix = [[1,2,3], [4,5,6], [7,8,9]];
elements in array literals can be arbitrary expressions:
var base = 1024;
var table = [base, base+1, base+2, base+3];
specify undefined elements:
var sparseArray = [1,,,,5];
null represents no object, a special value of object type.
undefined stands for a variable that has been declared but had no value assigned or an object property not exist.
Although undefined and null are not the same, == operator equal them. Because the two kind value usually indicate an absence of value. If you want to distinguish the above two you can use === or typeof operator.
Difference between null and undefined:
The latter is not a key word. ECMAScript v3 implement it by defining a global variable named undefined not assign a value in advance. You can implement that by defining one yourself ,just like “var undefined”.
void operator can return an undefined value too.
in order to represent date and time js provide a class of object. Examples are following:
var now = new Date( );// Create an object holding the current date and time.
// Create a Date object representing Christmas.
// Note that months are zero-based, so December is month 11!
var xmas = new Date(2006, 11, 25);
there are methods to set and get the various date and time values and to convert the Date to string, using local time or GMT time. We will learn that in detail later.
Regular expressions are used for pattern matching and for implementing search and replace operations.
Regular expressions are represented by the RegExp object.
RegExp can be created like Date using RegExp().
Also, RegExp can be create using a literal syntax as following:
/^HTML/
/[1-9][0-9]*/
//bjavascript/b/i
ECMAScript v3 defines a number of classes to represent errors.

Table 3-3. Automatic datatype conversions
Value
Context in which value is used
String
Number
Boolean
Object
Undefined value
"undefined"
NaN
false
Error
null
"null"
0
false
Error
Nonempty string
As is
Numeric value of string or NaN
TRue
String object
Empty string
As is
0
false
String object
0
"0"
As is
false
Number object
NaN
"NaN"
As is
false
Number object
Infinity
"Infinity"
As is
true
Number object
Negative infinity
"-Infinity"
As is
TRue
Number object
Any other number
String value of number
As is
true
Number object
true
"true"
1
As is
Boolean object
false
"false"
0
As is
Boolean object
Object
toString( )
valueOf( ), toString( ), or NaN
true
As is
We can use values of the type string like an object as following:
var s = "These are the times that try people's souls.";
var last_word = s.substring(s.lastIndexOf(" ")+1, s.length);
But string is not object so what’s happen?
Js provide corresponding object classes for each of the three primitive data types, Number, String and Boolean classes.
Number, String, Boolean are wrappers which define properties and methods other than contain primitive values.
Note that the String object created when a string used in an object context is a transient one. It allows you to access a property or method, and then it is no longer needed, so reclaimed by the system. For example, var len = s.length;
In this case, s remains a string. A new transient object is created to access the length property. And then the object is discarded with no change to the original value s.
Note that strings are automatically converted to String objects when needed. Also, the reverse is true. for examples,
msg = S + '!';
in the above case, S is a String object. It need to convert to a primitive string type in order to add with !.
Note that the discuss about string and String also applies to number and Number, boolean and Boolean.
An explicit way to use wrapper as
var number_wrapper = Object(3);
Something simple about this subject has been discussed in 1.3.6 . there are something more in detail.
Object à number:
Object.valueOf()
If not return a primitive number value call Object.toString(). And convert the string value to a number.
This leads to interesting results for arrays. The toString( ) method of arrays converts the array elements to strings, then returns the result of concatenating these strings, with commas in between. Therefore, an array with no elements converts to the empty string, which converts to the number zero! Also, if an array has a single element that is a number n, the array converts to a string representation of n, which is then converted back to n itself. If an array contains more than one element, or if its one element is not a number, the array converts to NaN.
The conversion of a value depends on the context used.
Because +, <, <=, >, >= operate on both strings and numbers it is not clear whether to convert an object operator to a number or a string. In most cases, js first try to convert the object using valueOf(). If a primitive value( usually a number ) returned that value is used. Else js tries to convert the object to a string by calling toString().
But there is an exception for Date. Because Date has both valueOf() and toString(). Sometimes you may want use a string, other times may use a number.
Most object either have no valueOf() or don’t have a valueOf() that returns an useful value. So they referred as strings.
Note that valueOf() don’t convert an object to a number, its job is converting an object to a primitive value, maybe sometimes a string.
there are three ways to manipulate a data value.
firstcopy it.
Second pass it as an argument to a function or method.
Third compare it with another value.
Primitive types are manipulated by value, and reference types are manipulated by reference. Objects are reference types. Numbers and booleans are primitive types. Strings are a little difference.
Objects contain arbitrary numbers of properties or elements, so manipulating they by value is not inefficient. Although a string has arbitrary length it is usually considered as primitive type as it is not an object. We will discuss about it later.
Copying, passing, comparing by value:

// First we illustrate copying by value
var n = 1;// Variable n holds the value 1
var m = n;// Copy by value: variable m holds a distinct value 1
// Here's a function we'll use to illustrate passing by value
// As we'll see, the function doesn't work the way we'd like it to
function add_to_total(total, x)
{
total = total + x;// This line changes only the internal copy of total
}
// Now call the function, passing the numbers contained in n and m by value.
// The value of n is copied, and that copied value is named total within the
// function. The function adds a copy of m to that copy of n. But adding
// something to a copy of n doesn't affect the original value of n outside
// of the function. So calling this function doesn't accomplish anything.
add_to_total(n, m);
// Now, we'll look at comparison by value.
// In the following line of code, the literal 1 is clearly a distinct numeric
// value encoded in the program. We compare it to the value held in variable
// n. In comparison by value, the bytes of the two numbers are checked to
// see if they are the same.
if (n == 1) m = 2;// n contains the same value as the literal 1; m is now 2

Copying, passing, and comparing by reference

// Here we create an object representing the date of Christmas, 2007
// The variable xmas contains a reference to the object, not the object itself
var xmas = new Date(2007, 11, 25);
// When we copy by reference, we get a new reference to the original object
var solstice = xmas;// Both variables now refer to the same object value
// Here we change the object through our new reference to it
solstice.setDate(21);
// The change is visible through the original reference, as well
xmas.getDate( );// Returns 21, not the original value of 25
// The same is true when objects and arrays are passed to functions.
// The following function adds a value to each element of an array.
// A reference to the array is passed to the function, not a copy of the array.
// Therefore, the function can change the contents of the array through
// the reference, and those changes will be visible when the function returns.
function add_to_totals(totals, x)
{
totals[0] = totals[0] + x;
totals[1] = totals[1] + x;
totals[2] = totals[2] + x;
}
// Finally, we'll examine comparison by reference.
// When we compare the two variables defined above, we find they are
// equal, because they refer to the same object, even though we were trying
// to make them refer to different dates:
(xmas == solstice)// Evaluates to true
// The two variables defined next refer to two distinct objects, both
// of which represent exactly the same date.
var xmas = new Date(2007, 11, 25);
var solstice_plus_4 = new Date(2007, 11, 25);
// But, by the rules of "compare by reference," distinct objects are not equal!
(xmas != solstice_plus_4)// Evaluates to true

Copying, passing, comparing strings:
Because strings are immutable there is no way to tell whether strings are passed by value or by reference. You can assume that, for efficiency, JavaScript is implemented so that strings are passed by reference, but in actuality it doesn't matter, because it has no practical bearing on the code you write. That means that you can’t change a string whether it is used by reference or by value. so it does not matter which ways to use.
Strings are compared by value. be careful for the code following, which shows that comparison is done by value while it means a comparison by reference.
// Determining whether strings are compared by value or reference is easy.
// We compare two clearly distinct strings that happen to contain the same
// characters. If they are compared by value they will be equal, but if they
// are compared by reference, they will not be equal:
var s1 = "hello";
var s2 = "hell" + "o";
if (s1 == s2) document.write("Strings compared by value");
javascript is an untyped language. Java is strongly typed language which has the advantage of enforcing strict programming practices , which is suitable for long complex programs. The advantage of js is that it can conveniently and automatically convert values between different types. And codes in js is shorter, so simpler syntax is better.
variables defined with var are permanent, which can’t be deleted with delete operator.
If you assign a value to a variable you don’t declare with var, js implicitly declare it for you.
Note that the implicit declaration always create a global variable, even if it is used within a body of a function.
unlike java and so on, js does not have block-level scope. All variables declared in a function are defined throughout the function, no matter where they are declared. It means that in the following cods i, j, and k all have the same scope: throughout the body of function test.
function test(o) {
var i = 0; // i is defined throughout function
if (typeof o == "object") {
var j = 0; // j is defined everywhere, not just block
for(var k=0; k < 10; k++) { // k is defined everywhere, not just loop
document.write(k);
}
document.write(k); // k is still defined: prints 10
}
document.write(j); // j is defined, but may not be initialized
}
Another useful example:
var scope = "global";
function f( ) {
alert(scope); // Displays "undefined", not "global"
var scope = "local";// Variable initialized here, but defined everywhere
alert(scope); // Displays "local"
}
f( );
garbage collection is automatic and invisible to the programmer.
variables are fundamentally the same as object properties.
When the JavaScript interpreter starts up, one of the first things it does, before executing any JavaScript code, is create a global object. The properties of this object are the global variables of JavaScript programs. When you declare a global JavaScript variable, what you are actually doing is defining a property of the global object.
The JavaScript interpreter initializes the global object with a number of properties that refer to predefined values and functions. For example, the Infinity, parseInt, and Math properties refer to the number infinity, the predefined parseInt( ) function, and the predefined Math object, respectively.
In top-level code you can use this to refer to the global object. In a function this has a different use.
Like that global variables are properties of the special global object, local variables are properties of an object which known as the call object. While the body of a function is executing, the function arguments and local variables are stored as properties of this call object. The use of an entirely separate object for local variables is what allows js to keep local variables from overwriting the value of global variables with the same name.
Each time the js interpreter begins to execute a function; it creates a new execution context for that function, where js codes execute. An important part of the context is the object in which variables defined.
Note that js implementations may allow multiple global execution context, each with a global object, such as client-side javascript, in which each separate browser window, or each frame within a window, defines a separate global execution context.
When JavaScript code in one execution context can read and write property values and execute functions that are defined in another execution context, you've reached a level of complexity that requires consideration of security issues.
Interpret the topic of variables scope with knowledge of execution context:
Every JavaScript execution context has a scope chain associated with it. This scope chain is a list or chain of objects. When JavaScript code needs to look up the value of a variable x (a process called variable name resolution), it starts by looking at the first object in the chain. If that object has a property named x, the value of that property is used. If the first object does not have a property named x, JavaScript continues the search with the next object in the chain. If the second object does not have a property named x, the search moves on to the next object, and so on.
In top-level JavaScript code (i.e., code not contained within any function definitions), the scope chain consists of a single object, the global object. All variables are looked up in this object. If a variable does not exist, the variable value is undefined. In a (nonnested) function, however, the scope chain consists of two objects. The first is the function's call object, and the second is the global object. When the function refers to a variable, the call object (the local scope) is checked first, and the global object (the global scope) is checked second. A nested function would have three or more objects in its scope chain. The figure bellow illustrates the process of looking up a variable name in the scope chain of a function.
==equality, ===identity
!==inequlity, !===inidentity
operators:

Table 5-1. JavaScript operators
P
A
Operator
Operand type(s)
Operation performed
15
L
.
object, identifier
Property access
L
[]
array, integer
Array index
L
( )
function, arguments
Function call
R
new
constructor call
Create new object
14
R
++
lvalue
Pre- or post-increment (unary)
R
--
lvalue
Pre- or post-decrement (unary)
R
-
number
Unary minus (negation)
R
+
number
Unary plus (no-op)
R
~
integer
Bitwise complement (unary)
R
!
boolean
Logical complement (unary)
R
delete
lvalue
Undefine a property (unary)
R
typeof
any
Return datatype (unary)
R
void
any
Return undefined value (unary)
13
L
*, /, %
numbers
Multiplication, division, remainder
12
L
+, -
numbers
Addition, subtraction
L
+
strings
String concatenation
11
L
<<
integers
Left shift
L
>>
integers
Right shift with sign extension
L
>>>
integers
Right shift with zero extension
10
L
<, <=
numbers or strings
Less than, less than or equal
L
>, >=
numbers or strings
Greater than, greater than or equal
L
instanceof
object, constructor
Check object type
L
in
string, object
Check whether property exists
9
L
==
any
Test for equality
L
!=
any
Test for inequality
L
===
any
Test for identity
L
!==
any
Test for nonidentity
8
L
&
integers
Bitwise AND
7
L
^
integers
Bitwise XOR
6
L
|
integers
Bitwise OR
5
L
&&
booleans
Logical AND
4
L
||
booleans
Logical OR
3
R
?:
boolean, any, any
Conditional operator (three operands)
2
R
=
lvalue, any
Assignment
R
*=, /=, %=, +=, -=, <<=, >>=, >>>=, &=, ^=, |=
lvalue, any
Assignment with operation
1
L
,
any
Multiple evaluation
delete:
Not all variables and properties can be deleted by delete. Some built-in core and client-side properties are immune from deletion, and user defined variables with var can’t be deleted too.
Note that if a nonexistent property is deleted it returns true.
var o = {x:1, y:2};// Define a variable; initialize it to an object
delete o.x; // Delete one of the object properties; returns true
typeof o.x; // Property does not exist; returns "undefined"
delete o.x; // Delete a nonexistent property; returns true
delete o; // Can't delete a declared variable; returns false
delete 1; // Can't delete an integer; returns true
x = 1; // Implicitly declare a variable without var keyword
delete x; // Can delete this kind of variable; returns true
x; // Runtime error: x is not defined
It is important to understand that delete affects only properties, not objects the properties referred to by those properties. Consider the following code:
var my = new Object( ); // Create an object named "my"
my.hire = new Date( ); // my.hire refers to a Date object
my.fire = my.hire; // my.fire refers to the same object
delete my.hire; // hire property is deleted; returns true
document.write(my.fire);// But my.fire still refers to the Date
object
void:
the purpose of void is to discard its operand value and return undefined.
()
is a operator, which is used to invoke function.
for/in:
 for (variable in object)
statement
l execute once for each property of object. And the names of properties is assigned to variable one by one.
 for (var prop in my_object) {
document.write("name: " + prop + "; value: " + my_object[prop], "<br>");
}
the above code prints the name and value of each property.
l Variables in for/in loop can be an expression, as long as it evaluates to something suitable for the left side of an assignment. The expression will be evaluated each time through the loop.
var o = {x:1, y:2, z:3};
var a = new Array( );
var i = 0;
for(a[i++] in o) /* empty loop body */;
the code above is the same as functionally:
a[0]=x;
a[1]=y;
a[2]=z;
l when the object in for/in is an array the loop enumerates the array indexes.
var a= [1,2,3];
for(i in a) alert(i);
the code above is functionally the same as:
i=0;
i=1;
i=2;
0,1,2 are the indexes of the array a.
functions:
function funcname([arg1 [,arg2 [..., argn]]]) {
statements
}
a function definition creates a new function object and stores that object in a newly created property named funcname.
Technically speaking, the function statement is not a statement. Statements cause dynamic behavior in a javascript program, while function definitions describe the static structure of a grogram. Statements are executed at runtime, functions are defined when js code is parsed, or compiled, before it is actually run. The situation above cause some surprising effects.
alert(f(4)); // Displays 16. f( ) can be called before it
is defined.
var f = 0; // This statement overwrites the property f.
function f(x) {// This "statement" defines the function f
before either
return x*x;// of the lines above are executed.
}
alert(f); // Displays 0. f( ) has been overwritten by
the variable f.
try/catch/finally:
try/finally:
when used above the finally block is simply cleanup code, regardless of break, continue, or return within the try clause

Table 6-1. JavaScript statement syntax
Statement
Syntax
Purpose
break
break;
break label;
Exit from the innermost loop or switch statement or from the statement named by label
case
case expression:
Label a statement within a switch statement
continue
continue;
continue label;
Restart the innermost loop or the loop named by label
default
default:
Label the default statement within a switch statement
do/while
do
statement
while (expression);
An alternative to the while loop
empty
;
Do nothing
for
for (initialize ; test ; increment)
statement
An easy-to-use loop
for/in
for (variable in object)
statement
Loop through the properties of an object
function
function funcname([arg1[..., argn]])
{
statements
}
Declare a function
if/else
if (expression)
statement1
[else statement2]
Conditionally execute code
label
identifier: statement
Give statement the name identifier
return
return [expression];
Return from a function or return the value of expression from a function
switch
switch (expression) {
statements
}
Multiway branch to statements labeled with case or default:
throw
throw expression;
Throw an exception
try
try {
statements
}
catch (identifier) {
statements
}
finally {
statements
}
Catch an exception
var
var name_1 [ = value_1]
[ ,..., name_n [ = value_n]];
Declare and initialize variables
while
while (expression)
statement
A basic loop construct
with
with (object)
statement
Extend the scope chain (deprecated)
Although you can declare a variable with var there is no need to do with object properties. Once you have create an object property by assigning a value to it, you can change the value of properties at any time.
To check the existence of a property you can use in operator like “if (“propertyname” in objectname)”.
A similar way to check the existence of a property is :
If (objectname.propertyname !== undefined). Because if a property exists but has no value it values undefined. The above check that If the property exists and is not undefined.
If you delete a property of an object using delete, you not merely set the property to undefined but also remove it from the object.
The difference between object.property and object[“property”]:
The former use an indentity(property) and the latter uses a string. Identities can’t be manipulated but strings can. That is that in c or so on the number of property in an object is fixed, but it is not true in javascript. What’s more, if the property is an identity it must be typed literally into your program. You can manipulate the properties which are strings, which has great flexibility.
var addr = "";
for(i = 0; i < 4; i++) {
addr += customer["address" + i] + '/n';
}
All objects in javascript inherit from the Object class.
The property and methods in Ojbect:
l constructorproperty:
theconstructor property refers to the constructor function that initialize the object.
var d = new Date();
d.constructor == Date;// Evaluates to true
also, instanceof operator exists.
l toString():
l toLocalString():
the default implementation doesn’t do any localization. It returns the same as toString().
l hasOwnProperty():
to check that if the object define a noninherited property of the specific name .
l propertyIsEnumarable():
l isPrototypeOf():
you can define nonnumeric object properties on an array and access them using the . or [] syntax:
a[-1.23] = true;
because -1.23 can be an index obviously it is converted to a string “-1.23” and named a property which has a boolean value true.
arrays may be sparse which means that array indexes need not to be a continues range of numbers.
delete operator only sets an array element to undefined not remove it from the array. To actually delete an element, so that all elements above it are shifted down to lower indexes, you must use an array method. Array.shift() deletes the first element of an array, Array.pop() deletes the last element, and Array.splice() deletes a contiguous range of elements from an array.
Length of array:
var a = new Array(); // a.length == 0(no elements defined)
a = new Array(10); // a.length == 10 (empty elements 0-9 defined)
a = new Array(1,2,3);// a.length == 3(elements 0-2 defined)
a = [4, 5]; // a.length == 2(elements 0 and 1 defined)
a[5] = -1; // a.length == 6(elements 0, 1, and 5 defined)
a[49] = 0; // a.length == 50 (elements 0, 1, 5, and 49 defined)
length property of an array is read/write value.
so setting length to a smaller value than its current value truncates the array to the new value and some elements are discarded. If you set a larger value new undefined values are added to increase the array to the new size.
Js doesn’t support muiltidimensional arrays, but it does allow you to approximate them quite nicely with arrays of arrays.
Array methods:
l join():
convert all the elements of an array to strings and concatenate them:
var a = [1, 2, 3]; // Create a new array with these three
elements
var s = a.join(); // s == "1,2,3"
Note:
var t = a.join(“, ”); // t==”1, 2, 3”
use “, ” as the delimiter.
l revers():
l sort():
no arguments: sort alphabetically.
Use a function as the argument: sort by some order selfdefined:
var a = [33, 4, 1111, 222];
a.sort(); // Alphabetical order:1111, 222, 33, 4
a.sort(function(a,b) { // Numerical order: 4, 33, 222, 1111
return a-b; // Returns < 0, 0, or > 0, depending on order
});
l concate():
if the arguments are arrays they are flattend and then added to the array.
var a = [1,2,3];
a.concat(4, 5) // Returns [1,2,3,4,5]
a.concat([4,5]); // Returns [1,2,3,4,5]
a.concat([4,5],[6,7]) // Returns [1,2,3,4,5,6,7]
a.concat(4, [5,[6,7]])// Returns [1,2,3,4,5,[6,7]]
[5,[6,7]] in the last statement is flatted as 5,[6,7], so [5,[6,7]] is added and the returned array is [1,2,3,4,5,[6,7]]
l slice():
if the argument is negative it means the offset from the last element.
var a = [1,2,3,4,5];
a.slice(0,3); // Returns [1,2,3]
a.slice(3); // Returns [4,5]
a.slice(1,-1); // Returns [2,3,4]
a.slice(-3,-2);// Returns [3]
l splice():
it can insert and remove elements from an array.
l push(), pop():
work with arrays as if they are stacks.
l unshift(), shift():
work with arrays as if they are queues.
l toString(), toLocalString():
note that the result doesn’t contain any square brackets or any other delimiter:
[1,2,3].toString() // Yields '1,2,3'
["a", "b", "c"].toString()// Yields 'a,b,c'
[1, [2,'c']].toString() // Yields '1,2,c'
l methods for firefox:
indexOf, lastIndexOf(), forEach(), map(), filter()
It is often perfectly reasonable to treat any object with a length property and corresponding nonnegative integer properties as a kind of array. These “array-like” objects actually do occasionally appear in practice although you can’t invoke array methods on them or except special behavior from the length property, you can still iterate through them with the same code you’d use for a true array. As long as you don’t add elements or change the length property you can treat an array-like object as a real array.
var a = {};// Start with a regular empty object
// Add properties to make it "array-like"
var i = 0;
while(i < 10) {
a[i] = i * i;
i++;
}
a.length = i;
// Now iterate through it as if it were a real array
var total = 0;
for(var j = 0; j < a.length; j++)
total += a[j];
note that In client-side JavaScript, a number of DOM methods, such as document.getElementsByTagName(), return array-like objects.
function literals:
unnamed:
var f = function(x) { return x*x; };
named(in order to recurs etc. ):
var f = function fact(x) { if (x <= 1) return 1; else return
x*fact(x-1); };
function statements:
function f(x) { return x*x; }
because function literals are created by js expressions they are quite flexible and particularly well suited for functions that are used only once and need not to named.
When a function invoked with fewer arguments than declared the additional arguments have the undefined value.
The arguments object within a function:
There is an Arguments object named arguments within the body of a function. The Arguments object is an array-like object. Although functions declare a fixed number of arguments it can be passed any number of arguments. The Arguments object allows full access to these argument values, even when some or all are unnamed. If you define a function with one arguments but you call it with two. You can access the second argument by arguments[1]. Furthermore, arguments has a length property, like true arrays.
The arguments can be used in many ways.
To verify that a function is invoked with the correct number of arguments:
function f(x, y, z)
{
// First, verify that the right number of arguments was passed
if (arguments.length != 3) {
throw new Error("function f called with " + arguments.length +
"arguments, but it expects 3 arguments.");
}
// Now do the actual function...
}
variadic functions:
with arguments it is possible that: js functions can be written so that they work with any number of arguments. This kind of functions are called variadic functions.
There is an example that shows how to find out the biggest number from any number of numbers:
function max(/* ... */)
{
var m = Number.NEGATIVE_INFINITY;
// Loop through all the arguments,
looking for, and
// remembering, the biggest
for(var i = 0; i < arguments.length; i++)
if (arguments[i] > m) m = arguments[i];
// Return the biggest
return m;
}
var largest = max(1, 10, 100, 2, 3, 1000, 4, 5, 10000, 6);
now you can see that you can’t imagine how many numbers will be compared. With arguments you don’t need to care about the number of arguments that functions need.
arguments is not an array. It is an object.
It defides numbered array elements and a length property.
arguments is not a reserved word so it can be hided if you define your own arguments variable. You’d better treat it as a reserved word.
calleeproperty:
arguments has a callee property referring to the function. It can be used to invoke an unnamed function itself recursively.
Because javascript is an untyped and flexible language sometimes it is better to do some type verifying when the value you need is some specific type data.
Functions in js can also be data besides syntax. It means that functions can be assigned to variables, stored in the properties of objects or the elements of arrays, passed as arguments to functions, and so on.
l We can look functions as below:
functionsquare(x){return x*x;}
the code creates a new function object and assigns it to the variable square. The function can also be assigned to another variable:
var b = square;// Now b refers to the same function that square
does
var c = b(5); // c contains the number 25
l functions can also be assigned to object properties.
var o = new Object;
o.square = function(x) { return x*x; } // function literal
y = o.square(16); // y equals 256
l functions don’t even require names at all when they are assigned to array elements:
var a = new Array(3);
a[0] = function(x) { return x*x; }
a[1] = 20;
a[2] = a[0](a[1]); // a[2] contains 400
l passing a function as an argument to other functions.
The codes following are quite different in behaviors compared with java, c++ and so on.
// We define some simple functions here
function add(x,y) { return x + y; }
function subtract(x,y) { return x - y; }
function multiply(x,y) { return x * y; }
function divide(x,y) { return x / y; }
// Here's a function that takes one of the above functions
// as an argument and invokes it on two operands
function operate(operator, operand1, operand2)
{
return operator(operand1, operand2);
}
// We could invoke this function like this to compute the value (2+3) + (4*5):
var i = operate(add, operate(add, 2, 3), operate(multiply, 4, 5));
// For the sake of the example, we implement the simple functions again, this time
// using function literals within an object literal;
var operators = {
add: function(x,y) { return x+y; },
subtract: function(x,y) { return x-y; },
multiply: function(x,y) { return x*y; },
divide: function(x,y) { return x/y; },
pow: Math.pow// Works for predefined functions too
};
// This function takes the name of an operator, looks up that operator
// in the object, and then invokes it on the supplied operands. Note
// the syntax used to invoke the operator function.
function operate2(op_name, operand1, operand2)
{
if (typeof operators[op_name] == "function")
return operators[op_name](operand1, operand2);
else throw "unknown operator";
}
// We could invoke this function as follows to compute
// the value ("hello" + " " + "world"):
var j = operate2("add", "hello", operate2("add", " ", "world"))
// Using the predefined Math.pow() function:
var k = operate2("pow", 10, 2)
When a function is assigned to a property of an object, it is often referred to as a method of that object.
l To assign a function to a property:
Object.property = function;
To invoke:
Object.property();
l To use “this” in method to refer to the object that contains the method:
var calculator = {// An object literal
operand1: 1,
operand2: 1,
compute: function() {
this.result = this.operand1 + this.operand2;
}
};
calculator.compute(); // What is 1+1?
print(calculator.result); // Display the result
l when use “this” in a function which is not invoked as a method “this” refer to the global object. Even when “this” exists in the nested functions which is contained by a method.
l the length property of the function itself is read only. It returns the number of arguments excepted.
l The prototype property:
l Defining your own properties:
When a function need a variable whose value persists across invocation you can use a property of the Function object instead of defining a global variable.
// Create and initialize the "static" variable.
// Function declarations are processed before code is executed, so
// we really can do this assignment before the function declaration.
uniqueInteger.counter = 0;
// Here's the function. It returns a different value each time
// it is called and uses a "static" property of itself to keep track
// of the last value it returned.
function uniqueInteger() {
// Increment and return our "static" variable
return uniqueInteger.counter++;
}
l apply() and call()
Functions are lexically. This means that they run in the scope in which they are defined, not the scope from which they are executed. When a function is defined, the current scope chain is saved and becomes part of the internal state of the function. At the top level, the scope chain simply consists of the global object, and lexical scoping is not particularly relevant. When you define a nested function, however, the scope chain includes the containing function. This means that nested functions can access all of the arguments and local variables of the containing function.
When the javascript interpreter invokes a function, it first sets the scope to the scope chain that was in the effect when the function was defined. Next it adds a new object known as the call object to the front of the scope chain. The call object is initialized with a property named arguments. so arguments of the function are added into the arguments object and local variables declared with the var statement are also defined within the call object.
It is sometimes useful to define a function simply to create a call object. The call object acts as a temporary namespace where you can define variables and create properties without corrupting the global namespace.
If there a piece of code you want to use in other pieces of codes. But there are variables acting as intermediate results. The problem is that since this code will be used in many different programs, you don't know whether the variables it creates will conflict with variables used by the programs that import it. So the solution is to put that piece of code into a function and then invoke it.
Considering the code following:
// This function returns a function each time it is called
// The scope in which the function is defined differs for each call
function makefunc(x) {
return function() { return x; }
}
// Call makefunc() several times, and save the results in an array:
var a = [makefunc(0), makefunc(1), makefunc(2)];
// Now call these functions and display their values.
// Although the body of each function is the same, the scope is
// different, and each call returns a different value:
alert(a[0]());// Displays 0
alert(a[1]());// Displays 1
alert(a[2]());// Displays 2
when a function is invoked a call object is created and placed on the scope chain. When the function exists the call object is removed from the scope chain. When no nested functions are involved, the scope chain is the only reference to the call object. When the object is removed from the chain, there are no more references to it and it is garbage collected.但是当有内嵌的函数时情况有点不同。当一个内嵌函数被生成时,该函数的定义就会指向call对象,因为call对象在scope chain的顶端。如果内嵌的函数只在外部的函数中使用的话,那么指向内嵌函数的引用只能在call对象中找到。当外部函数返回,内嵌函数指向call,call指向内嵌函数,没有其他的引用了。因此,这两者都会被垃圾收集。
a function can also be defined with the Function() constructor like:
var f = new Function(“x”, “y”, “return x*y”);
the code above is the same as functionally:
function f(x,y){return x*y;}
The Function() constructor has any number of string arguments and the last one is the body of the function. Note that the function created by the Function() has no name.
Function() constructor allows the function code to be dynamically created and compiled at runtime.
Function() constructor parses the function code and create a new function object each time it is called. So if the Function() exists within a loop or a frequently called code and Function() may be called for many times. It is inefficient. By contrast, a function literal or nested function is not recompiled every time.
The functions the Function() creates don’t use lexical scoping. They are compiled as if they were in top-level.
var y = "global";
function constructFunction() {
var y = "local";
return new Function("return y");// Does not capture the local scope!
}
// This line displays "global" because the function returned by the
// Function() constructor does not use the local scope. Had a function
// literal been used instead, this line would have displayed "local".
alert(constructFunction()());// Displays "global"
pay attention to the two “()”. If you write constructFunction() it displays :
function annoymouse(){
return y;
}
example codes:
// Define the constructor.
// Note how it initializes the object referred to by "this".
function Rectangle(w, h) {
this.width = w;
this.height = h;
// Note: no return statement here
}
// Invoke the constructor to create two Rectangle objects.
// We pass the width and height to the constructor
// so that it can initialize each new object appropriately.
var rect1 = new Rectangle(2, 4); // rect1 = { width:2, height:4 };
var rect2 = new Rectangle(8.5, 11); // rect2 = { width:8.5, height:11 };
Note that the constructor usually doesn’t return a value. If you return an object value the returned value becomes the value of the new expression. In this case the object that was the value of this is discard.
We can assign a function to a property of an object. So the function is a method, just like:
function Rectangle(w, h) {
this.width = w;
this.height = h;
this.area = function( ) { return this.width * this.height; }
}
of course, width and height properties are always different. But the method area is always referred to the same function. It is inefficient to use regular properties for methods that are intended to be shared by all objects of the same class. And sometimes the method may want to be changed.
There is an internal reference to each object’s prototype object within every object.
When a function is defined there is a prototype property automatically created and initialized. The prototype property is that is an object with a property named constructor initially which refers back to the constructor function with which the prototype is associated. Any properties added to this prototype object will appear t be properties of objects initialized by the constructor.
// The constructor function initializes those properties that
// will be different for each instance.
function Rectangle(w, h) {
this.width = w;
this.height = h;
}
// The prototype object holds methods and other properties that
// should be shared by each instance.
Rectangle.prototype.area = function( ) { return this.width * this.height; }
The prototype object is associated with the constructor, and each object initialized by the constructor inherits the same set of properties from the prototype. It means that the prototype object is an ideal place for methods and other constant properties.
Note that although inheriting happens properties are not copied from the prototype object into new objects. They appears as if they were properties of new objects.
It has two important implications.
The use of prototype objects can dramatically decrease the amount of memory required by each object because the object can inherit many of its properties.
You can add new methods to existing classes which is not a good idea.
The discussion following is from core javascript guide 1.5

Objects and arrays are different interfaces to the same data structure.
To create an object using a constructor function:
1 define the object type by writing a constructor function.
2 create an instance of the object with new.
Note that you can add a new property to an instance at anytime like:
car2.newProperty = newValue;
But note that the new property merely affect the instance car2 not any other instances of the same object type. If you want to add a new property to an object type you should manipulate on the object type.
You can refer a property by name or ordinal index. But if you define a property with a name you may always refer to it by name, and if you define a property with an index you must always refer to it by an index.
Class-based versus prototype-based languages
For class-based languages there is a distinction between classes and instances.
For prototype-based languages there is not.
They simply have objects.
And there is concept of a prototype object which used as a template to get initial properties for a new object.
Any object can be the prototype of another object.
Any object can specify its own properties at any time whether you create it or run it.
In classed-based languages there is a separate fragment of class defining where you can specify constructor methods. A constructor can specify initial values for the instance’s properties and perform other processing appropriate at creation time.
In javascript you define a constructor function to create objects with a particular initial set of properties and values. Any javascript function can be used as a constructor. You use new operator with a constructor with a constructor function to create to new object.
Inheritance
Javascript implements inheritance by allowing you to associate a prototypical object with any constructor function. For example, you define the Employee constructor function with some properties. Next, you define the Manager constructor function with its own properties. Finally, you assign a new Employee object as the prototype for the Manager constructor function. Then when you create a new Manager, it inherits the properties from the Employee object.
Adding and removing properties
In class-based languages you can’t change the number of properties after your definition. But you can do it in javascript.
Table 8.1 Comparison of class-based (Java) and prototype-based (JavaScript) object systems
Class-based (Java)
Prototype-based (JavaScript)
Class and instance are distinct entities.
All objects are instances.
Define a class with a class definition; instantiate a class with constructor methods.
Define and create a set of objects with constructor functions.
Create a single object with the new operator.
Same.
Construct an object hierarchy by using class definitions to define subclasses of existing classes.
Construct an object hierarchy by assigning an object as the prototype associated with a constructor function.
Inherit properties by following the class chain.
Inherit properties by following the prototype chain.
Class definition specifies all properties of all instances of a class. Cannot add properties dynamically at run time.
Constructor function or prototype specifies an initial set of properties. Can add or remove properties dynamically to individual objects or to the entire set of objects.
There is an example which shows the differences between java and javascript.
to implements the hierarchy above we do in javascript:
what’s more:
JavaScript
Java
function Employee () {
this.name = "";
this.dept = "general";
}
public class Employee {
public String name;
public String dept;
public Employee () {
this.name = "";
this.dept = "general";
}
}
JavaScript
Java
function Manager () {
this.reports = [];
}
Manager.prototype = new Employee;
function WorkerBee () {
this.projects = [];
}
WorkerBee.prototype = new Employee;
public class Manager extends Employee {
public Employee[] reports;
public Manager () {
this.reports = new Employee[0];
}
}
public class WorkerBee extends Employee {
public String[] projects;
public WorkerBee () {
this.projects = new String[0];
}
}
JavaScript
Java
function SalesPerson () {
this.dept = "sales";
this.quota = 100;
}
SalesPerson.prototype = new WorkerBee;
function Engineer () {
this.dept = "engineering";
this.machine = "";
}
Engineer.prototype = new WorkerBee;
public class SalesPerson extends WorkerBee {
public double quota;
public SalesPerson () {
this.dept = "sales";
this.quota = 100.0;
}
}
public class Engineer extends WorkerBee {
public String machine;
public Engineer () {
this.dept = "engineering";
this.machine = "";
}
}
Note that “instance” in javascript does not have the same meaning as in class-based languages. In javascript we talk about “instance” as an object created using particular constructor function. So in the examples above jane is an instance of Engineer.
Note that although the terms parent, child, ancestor, and descendant do not have formal meanings in JavaScript; you can use them informally to refer to objects higher or lower in the prototype chain.
The following section shows that how an new object is created in more detail:
Mark = new WorkerBee;
1. In javascript, the new operator creates a new generic object and javascript passess this new object as the value of the this keyword to the WorkerBee constructor function.
2. Then the constructor function sets the value of the new object’s own properties. It also sets an internal _proto_ property to the value of WorkerBee.prototype. the _proto_ property determines the prototype chain used to return property values.
3. Then javascript returns the new object and sets the mark to the returned object.
4. javascript doesn’t explicitly put values that is herited from the prototype chain. When you ask for the value of a property, javascript will first check to see if the value exists in that object. if not to check from upper level in the prototype chain using the _proto_ property. And so on.
More about adding property
If you add a new property to an object that is used as the prototype for a constructor function, you add that property to all objects that inherit from it. For example,
how to specify initial values to the inherited properties:
for example:
function Engineer (name, projs, mach) {
this.base = WorkerBee;
this.base(name, "engineering", projs);
this.machine = mach || "";
}
if you create an object like:
jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
then something happen as these steps:
1. The new operator creates a generic object and sets its __proto__ property to Engineer.prototype.
2. The new operator passes the new object to the Engineer constructor as the value of the this keyword.
3. The constructor creates a new property called base for that object and assigns the value of the WorkerBee constructor to the base property. This makes the WorkerBee constructor a method of the Engineer object. The name of the base property is not special. You can use any legal property name; base is simply evocative of its purpose.
4. The constructor calls the base method, passing as its arguments two of the arguments passed to the constructor ("Doe, Jane" and ["navigator", "javascript"]) and also the string "engineering". Explicitly using "engineering" in the constructor indicates that all Engineer objects have the same value for the inherited dept property, and this value overrides the value inherited from Employee.
5. Because base is a method of Engineer, within the call to base, JavaScript binds the this keyword to the object created in Step 1. Thus, the WorkerBee function in turn passes the "Doe, Jane" and ["navigator", "javascript"] arguments to the Employee constructor function. Upon return from the Employee constructor function, the WorkerBee function uses the remaining argument to set the projects property.
6. Upon return from the base method, the Engineer constructor initializes the object's machine property to "belau".
7. Upon return from the constructor, JavaScript assigns the new object to the jane variable.
If you want to change the value of an object property at run time and have the new value be inherited by its descendants, you can’t define the property in the object’s constructor function. Because if you do so, you can see:
function obj1()
{
this.pro=””;
}
function obj2()
{}
obj2.prototype=new obj1;
Now you can see that there is an instance of obj1 assigned to obj2.prototype. It means that there is a local variabl prototype. So the pro property of obj2.prototype exists. If you change the pro of obj1, no affection may be made on obj2. And you can resolve this problem as:
function obj1()
{}
obj1.pro=””;
function obj2()
{}
obj2.prototype=new obj1;
In the case above if you change the pro property of obj1 the pro property inherited by obj2 from obj1 is also changed.
There is an example of prototype chain.
chris = new Engineer("Pigman, Chris", ["jsd"], "fiji");
With this object, the following statements are all true:
chris.__proto__ == Engineer.prototype;
chris.__proto__.__proto__ == WorkerBee.prototype;
chris.__proto__.__proto__.__proto__ == Employee.prototype;
chris.__proto__.__proto__.__proto__.__proto__ == Object.prototype;
chris.__proto__.__proto__.__proto__.__proto__.__proto__ == null;
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics