The operation of a computer program requires operating values such as the number 3.14 or the text "hello world". In programming languages, the type of value that can be represented and operated is called data type. The most basic feature of programming languages is to host multiple data types. When the program needs to keep the value for future use, it is assigned to ("save" the value to) a variable. A variable is a symbolic name of a value, and a reference to a value can be obtained by the name. The working mechanism of variables is a basic feature of programming languages. This chapter will refer to the previous section to help understand the content of this chapter, and will be explained in more depth later.
JavaScript data is divided into two categories: primitive type and object type
The original classes in javascript include numbers, strings, and boolean values. This chapter will have a separate chapter specifically discussing javascript's numbers, strings, and boolean values. JavaScript also has two special raw values, null (empty) and Undefined (undefined), they are not numbers, strings, or boolean values. They represent the only members of their respective special types.
JavaScript is an object besides numbers, strings, boolean values, null, and undefined. An object is a collection of properties. Each attribute consists of a "name/value pair" (the value can be a primitive value, such as a number, a string, or an object). One of the more special objects (global object will be introduced in Miss Fifth, and the sixth section will be described in more detail)
Normal javascript objects are no-necessary collections of "named values". JavaScript also defines a special object - an array, representing an ordered set of numbered values. JavaScript defines a dedicated syntax for arrays. Make arrays have some unique behavior properties that are different from ordinary objects.
JavaScript also defines a special object-function. A function is an object with executable code it wants to associate with. It runs the code by calling the function and returns the result of the operation. Like arrays, function behavior characteristics are different from other objects. JavaScript defines a special syntax for using functions. For javascript functions. Most importantly, they are all true values, and JavaScript can be used to treat them as ordinary objects.
If a function initializes (using the new operator) a new object, we call it a constructor. Each constructor defines a class object-a collection composed of constructor initialization objects. Classes can be regarded as subtypes of object types. In addition to array classes and function classes, JavaScript also defines three other classes used. A date defines an object representing a date. RegExp defines the object of regular expressions. The error class defines the line that represents the runtime error and syntax error object in a javascript program. You can define the required class by defining your own constructor.
The JavaScript interpreter has its own memory management mechanism, which can automatically garbage collection of memory. This means that the program can create objects on demand, and programmers do not have to worry about the destruction of these objects and the memory recycling. When no reference points to an object, the interpreter knows that the object is useless and will automatically recycle the memory resources it occupies.
Javascript is an object-oriented language. Not strictly speaking, this means that we do not use global definition functions to operate different types of values. The data type itself can define methods to use values. For example, to sort elements in array a, there is no need to pass a into sort() function, but to transfer a method sort()
a.sort(); //sort(a) object-oriented version
Technically, only javascript objects can have methods. However, numbers, strings, and boolean values also have their own methods. In javascript, only null and undefined are values that cannot have methods.
The types of javascript can be divided into primitive types and object types, and can be divided into types that can have methods and types that cannot have methods. It can also be divided into mutable and immutable types. Values of mutable types can be modified, and objects and arrays belong to mutable types: JavaScript programs can change the value of an object's attribute value and the value of array elements.
Numbers, booleans, nulls, and undefined are unchangeable types. For example, modifying the contents of an array itself doesn't make sense. A string can be regarded as an array of characters, and you can think it can be changed. However, in javascript, strings are immutable. You can access text at any position of a string, but JavaScript does not provide a way to modify the text content of the string all the time.
JavaScript can perform data type conversion freely. For example, if a number is used where the program expects to use a string, javascript will automatically convert the number to a string. If you expect to use a non-boolean value where the boolean value is used, JavaScript will also convert accordingly. In JavaScript, the "judgment equality" rules are used to "judgment equality" (equality)
JavaScript variables are untyped. Variables can be assigned to people and types. Variables can be declared using the var keyword. JavaScript adopts syntax scope. Variables not declared in any function are called global variables. They are visible anywhere in JavaScript's program.
1. Numbers
Unlike other programming languages, javascript does not distinguish between integer values and floating point values. All values in javascript are expressed by floating point values. When a number appears directly in a javascript program, we are a numeric literal, and javascript supports numeric direct quantities in multiple formats. (Note: Adding a negative sign (-) directly before any number can get their negative values) But the negative sign is a one-way inverse operator. , not a component of the grammar of direct numerical quantities. )
i integer type direct quantity
A decimal integer is represented by an array sequence in javascript
In addition to the decimal integer direct quantity, JavaScript also recognizes the values of the sixteen mechanism (16) as the cardinality. The so-called hexadecimal system is a direct quantity prefixed with "0X" or "0x" followed by a string of hexadecimal numbers. The hexadecimal value is composed of letters between 0-9 and a(A)-f(F). The letters of af are expressed in numbers 10-15 below. Here are examples of direct quantities of hexadecimal integers
The code copy is as follows:
0xff //15*16+15=255
0xCAFE911
Although ECMAScript does not support octal direct quantities, some implementations of javascript can allow for the representation of integers in octal (base 8). The octal direct quantity starts with the number 0, followed by a sequence of numbers between 0 and 7.
The code copy is as follows:
0377 // 3*64 +7*8 +7 =255 (decimal)
Since some JavaScript implementations support octal inter-number, while some do not, it is best not to use integer inter-number prefixed with 0. After all, we cannot know whether the current JavaScript implementation supports octal parsing. In the strict mode of ECMAScript6, the direct octal quantity is explicitly prohibited.
ii. Floating point direct quantity
Floating point direct quantities can contain decimal points, and they use the traditional real number writing method. A real number consists of an integer part, a decimal point and a decimal part.
In addition, exponential counting method can also be used to represent floating point direct quantities. That is, the real number is followed by the letter E or e, followed by the positive and negative sign, and then an integer exponent is added. The numerical value represented by this counting method is an exponential power of the previous real number multiplied by 10.
Can be expressed in a more concise syntax
The code copy is as follows:
[digits][.digits][(E|e)[(+|-)]digits]
3.14
2345.455
.333333333333333333333333333333333
6.02e23 //6.02*10 to the 23rd power
1.255454E-23 //1.255454*10 to the 23rd power
Arithmetic operation in iii.javascript
JavaScript programs use arithmetic operators provided by the language province to perform numerical operations. These operators contain + - * / and the remaining (divided remainder) operator %
In addition to basic operators, JavaScript also supports more complex arithmetic operations. This line-complicated operation is implemented by functions and constants defined as properties of Math objects.
The code copy is as follows:
Math.pow(2, 53) //=>9007199254740992 document.write(Math.pow(2,53) )
Math.round(.6) //=>1.0 Round
Math.ceil(.6) //=>1.0 upward search
Math.floor(.6) //=>0.0 downwards
Math.abs(-5) //=>5 Find the absolute value
Math.max(x, y, z) //Return the maximum value
Math.min(x, y, z) //Return the minimum value
Math.random() // Generate a pseudo-random number greater than 0 and less than 1
Math.PI //pi
Math.E //e: The base of natural logarithm
Math.sqrt(3) //3 square root
Math.pow(3, 1 / 3) //3's cube root
Math.sin(0) //Trigonometric functions, as well as Math.cos, Math.atan, etc.
Math.log(10) //=>2.302585092994046 Natural logarithm with base 10
Math.log(512) / Math.LN2 //Log of 512 with base 2
Math.log(100) / Math.LN10 //Log of 100 with base 10
Math.exp(3) //E's power of three
Arithmetic operations in javascript will not report errors when overflow, underflow or divisible by zero. However, the numerical operation result exceeds the number that can be represented in javascript (overflow), and the result is a special infinite value (infinty) value, which is expressed as infinty in javascript. Similarly, when the value of the negative number exceeds the range of negative numbers that JavaScript can express, the result is negative infinity, which is expressed as -Infinty in JavaScript. The behavioral properties of infinity values are consistent with what we expect: the result of addition, subtraction, multiplication and division based on them is infinity (preserving the signs)
Underflow is a situation that occurs when the calculation result is wirelessly close to zero and is smaller than the minimum value that JavaScript can represent. When a negative number underflows, javascript returns a special value, "negative zero", which (negative zero) is almost exactly the same as normal zero. JavaScript programmers rarely use negative zeros.
JavaScript predefined global variables Infinaty and NaN to express non-numeric values. In ECMAScipt3, these two values can be read and written. ECMAScript5 fixed this issue by defining them as read-only. The attribute value defined by the Number object in ECMAScipt3 is also read-only, here are some examples:
The code copy is as follows:
Infinity //Initialize a readable/write variable to infinity
Number.POSITIVE_INFINITY //Same value, read only
1 / 0 //This is the same value
Number.MAX_VALUE + 1 //The calculation result is still Infinity
Number.NEGATIVE_INFINITY //Denotes negative infinity
-Infinity
-1/0
-Number.MAX_VALUE -1
NaN //Initialize a readable/write variable to NaN
Number.NaN //Same value, but read only
0/0 //The calculation result is still NaN
Number.MIN_VALUE/2 // Underflow occurred. Calculated result is 0
-Number.MIN_VALUE/2 //Negative zero
-1/Infinity //Negative zero
-0 //Negative zero
There is a little special about non-numeric values in javascript, which are not equal to humans and values, including themselves. In other words, it is impossible to judge whether x is NaN by x==NaN. Instead, x should be used! =x to judge that if and only when x is NaN, the result of the expression is true. The function isNaN() function is similar to this. If the parameter is NaN or a non-numeric value (such as a string and an object), it returns true. There is a similar function in javascript that isFinite(), which returns true when the parameters are not NaN, Infinty or -Infinity.
Negative zero value is also a bit special. It is equal to positive and negative zero (even judged using javascript's strict equality test), which means that these two values are almost exactly the same except as excluding:
The code copy is as follows:
var zero = 0;
var negz = -0;
zero === negz //=>true Positive and negative zero values are equal
1/zero === 1/negz //false Positive infinity and negative infinity are different
iiii.Binary floating point number and rounding error
There are countless real numbers, but JavaScript can only represent finite numbers through the form of floating point numbers (to be precise, there are 18 437 736 874 454 810 627), that is to say, when real numbers are used in JavaScript, it is often just an approximate representation of the real value.
JavaScript adopts IEEE-754 floating point number notation (used by almost all modern programming languages). This is a binary representation that can accurately represent fractions, such as 1/2 1/8 and 1/1024. Unfortunately, the fractions we often use, especially in financial calculations, are all based on decimal fractions 1/10, 1/100, etc. Binary notation cannot represent a simple number like 0.1.
Numbers in javascript have sufficient precision. And can be close to 0.1. But in fact, the inability to accurately express the numbers brings some problems.
The code copy is as follows:
var x = .3 - .2;
var y = .2 - .1;
alert(x == y) //=>false The two values are not equal
x == .1 //=>false .3-.2 does not equal .1
y == .1 //=>true .2-.1 equals 1
Due to rounding error, the approximate difference between 0.3 and 0.2 does not actually equal the approximate difference between 0.2 and 0.1 (in real simulation environments, 0.3-0.2=0.099 999 999 999 999 999 999 98). This problem is not only present in JavaScript, it is very important to understand this: this problem will occur in any programming language that uses binary floating point numbers. It is also important to note that the values of x and y in the above code are very close to each other and the final correct values. This calculation result can be competent for most calculation tasks. This problem only occurs when comparing whether the two values are equal.
Future versions of javascript may support decimal numeric types to avoid this problem, before that you may prefer to use large integers for important financial calculations. For example, use integer "segments" instead of decimal "elements" for monetary units.
iiiii.Date and Time
The core of the javascript language includes the Date() constructor, which originally created objects of date and time. The methods of these date objects provide a simple API for date calculation. Date objects cannot be a basic data type like numbers.
The code copy is as follows:
var zhen = new Date(2011, 0, 1); //January 1, 2011
var later = new Date(2011, 0, 1, 17, 10, 30); //Same day
var now = new Date(); //The current date and time
var elapsed = now - zhen; //Date subtraction. Calculate the number of milliseconds of the time interval
later.getFullYear(); //=>2011
later.getMonth(); //=>0 Months counted from 0
later.getDate(); //=>1 The number of days counted from 1
later.getDay(); //=>5 Get the day of the week. 0 represents Sunday, 5 represents Sunday
later.getHours() //=>Local time
later.getUTCHours() //Use UTC to represent the time of the hour, based on the time zone.
2. Text
A string is an immutable and ordered sequence of 16-bit values, each character usually comes from a Unicode character set. JavaScript represents text through string types. The length of a string is the number of 16-bit values it contains. The index of a javascript string (and its array) starts at 0. The length of the empty string is 0, and there is no "character type" representing a single character in JavaScript. To represent a 16-bit value, just assign it to a string variable. The length of this string is 1.
Character set, inner code and javascript string
JavaScript uses a UTF-16-encoded Unicode character set, and a javascript string is a sequence composed of a set of unordered 16-bit values. The most commonly used Unicode characters are represented by 16-bit inner codes and represent a single character in the string. Unicode characters that cannot be represented as 16-bit are followed by the UTF-16 encoding rules - using two 16-bit values to form a sequence (also known as "proxy pairs"). This means that a javascript string of length 2 (two 16-bit values) may represent a Unicode character.
The code copy is as follows:
var p ="π" ; //π is represented by 16-bit inner code 0x03c0
var e = "e"; //e is represented by 17-bit inner code 0x1d452
p.length // =>1 p contains a 16-bit value
e.length // =>2 e encoded by UTF-16 contains two values: "/ud835/udc52"
All string operation methods defined by javascript act on 16-bit values, not characters, and do not process the proxy item separately. Similarly, JavaScript will not standardize string processing. There is no guarantee that strings are legal UTF-16 format
i string direct quantity
A direct quantity of strings in a javascript program is a sequence of characters enclosed by single quotes or double quotes. A string delimited by single quotes can contain double quotes, and a string delimited by double quotes can also contain single quotes. Here are a few examples of direct quantification of strings.
The code copy is as follows:
"" //Empty string, 0 characters
'testing'
"3.14"
'name="myform"'
"wouldn't you prefer O'Reily's book?"
In ECMAScript3, the direct quantity of the string must be written in one line, while in ECMAScript5, the direct quantity of the string can be split into several lines, and each line must end with a backslash (/). Neither the backslash nor the line ending character are the contents of the direct quantity of the string. If you want to be together, you can use /n to escape characters.
It should be noted that when using single quotes to delimit strings, you need to be extra careful about the abbreviations and all formats in English. English apostrophes and single quotes are the same character, so backslashes (/) must be used to escape.
ii escape characters
In javascript strings, backslashes (/) have a special purpose. Adding a character to the backslashes will no longer represent their literal meaning. For example, /n is an escape character, which represents a newline.
The code copy is as follows:
/o //NUL characters
/b //Backspace character
/t //Horizontal tab character
/n //Line newline character
/v //Vertical tab character
/f //Page renewal
/r //Carriage return character
/" //Double quotes
// Backslash
/xXX Latin-1 character specified by two-bit hexadecimal
/xXXXXX Unicode character specified by four-bit hexadecimal XXXXX
Use of iii string
One of the built-in features of javascript is string concatenation. Use operator + for strings to represent string concatenation. For example
The code copy is as follows:
var msg = "hello" + "world"; //Generate the string hello world
To determine the length of a string - the number of 16-bit values it contains, you can use the length attribute, such as the length of the string s.
s.length
In addition to the length attribute, strings also provide many methods that can be called.
The code copy is as follows:
var s = "hello,world";
s.charAt(0); //"h" first character
s.charAt(s.length - 1) //"d" last character
s.substring(1, 4) //"ell" 2-4 characters
s.slice(1, 4) //ell Same as above
s.slice(-3) // The last 3 characters appear
s.indexOf(l ")//2 character l The first occurrence position
s.lastIndexOf("l") //10 The last time the character l appears
s.indexOf("l",3)//After position 3, the first position where the l character appears
s.split(",") //=> ["hello","world"] is separated into substrings
s.replace("h","H")// =>"Hllo,world" full text character replacement
s.toUpperCase() //=>"HELLO,WORLD"
In javascript, strings are fixed and unchanged. Methods like replace() and toUpperCase() return new strings, and the original characters themselves have not changed.
In ECMAScript, characters can be treated as read-only arrays. In addition to using the charAt() method, square brackets can also be used to access individual characters in a string. (16-bit value)
The code copy is as follows:
s = "hello,world"
s[0] //=>"h"
s[s.length-1] //=>"d"
Foxfire has supported string indexing for this method a long time ago, and most modern browsers (except IE) followed Mozailla's footsteps and completed this feature before ECMAScript was formed.
iiii pattern matching
JavaScript defines the RegExp() constructor, which is used to create objects that represent text pattern matching. These patterns are called "regular expressions", regular expression syntax in JavaScript Perl. Both String and RegExp objects define functions that use regular expressions to match patterns, find and replace.
RegExp object is not a basic data type in the language. Like Date, it is just a special object with a practical API. Regular expressions have complex syntax and rich APIs. It will be introduced in detail in Chapter 10. RegExp is a powerful and commonly used text processing tool, and here is just an overview.
Although RegExp is not a basic data type in the language, they still have direct quantities and can be used directly in JavaScript. The text between two slashes forms a direct quantity of a regular expression. The second slash may also follow one or more letters. Used to modify the meaning of the matching pattern. For example:
The code copy is as follows:
/^HTML/ //Match strings starting with HTML
/[1-9][0-9]*/ //Match a non-zero number, followed by any number
//bjavascript/b/i/ //Match the word javascript and ignore upper and lower case
The RegExp object defines many useful methods, and strings also have methods that can accept RegExp parameters. For example:
The code copy is as follows:
var text = "testing:1,2,3"; //Text example
var pattern = //d+/g //Match all instances containing one or more numbers
pattern.test(text) // =>true: The match is successful
text.search(pattern) //=>9: The position where the first match was successful
text.match(pattern) //=> ["1","2","3"]All matches form an array
text.repeat(pattern,"#"); //=>"testing:#,#,#"
text.split(//D+/); //=>["","1","2","3"]: Use non-numeric characters to intercept strings
3. Boolean value
Boolean values refer to true or false, on or off. This type has only two values, and the word true or false is reserved.
The results of comparison statements in javascript are usually boolean values. For example
a==4
This code is used to detect whether the value of a of the variable is equal to 4. If it is equal, the value is true, if the value is not equal, false
Boolean values are usually used in JavaScript control statements, such as if/else statements in JavaScript. If the boolean value is true, execute the first piece of logic, and if another piece of code is false, e.g.
The code copy is as follows:
if (a == 4)
b = b + 1;
else
a = a + 1;
Any javascript value can be converted to boolean values, and the following values are converted to false
The code copy is as follows:
undefined
null
0
-0
NaN
""//Empty string
All other values, including all objects (arrays), will be converted to true, false, and the above 6 values that can be converted to false are sometimes called "false values". JavaScript expects that when using a boolean value, the false value will be treated as false, and the true value will be treated as true.
Let’s take a look at an example. Adding the variable o is an object or null, you can use an if statement to detect whether o is a non-null value.
if(o!==null)...
The unequal operator "!==" compares o and null and gives the result true or false. You can first ignore the comparison statement here. null is a false value and the object is a true value.
if(o)...
For the first case, the code after if will be executed only when o is not null, and the limitations of the second case are not that strict. This if is executed only if o is not false or any false value (such as null or unfined).
Boolean contains the toString() method, so you can use this method to convert a string to "true" or "false", but it does not contain other useful methods, and in addition to this unimportant API, there are three important boolean operators.
&& operator, || operator and unary operator "!" perform a Boolean non-(NOT) operation. If the true value returns false, the false value returns true, for example
The code copy is as follows:
if ((x == 0 && y == 0) || !(z == 0)) {
//X and y are both zero or z are non-zero
}
4.null and undefined
null is a keyword in the JavaScript language. It represents a special value "null value". For null, it performs typeof() operation and returns object. That is to say, null can be considered as a special object value, meaning "non-object". But in fact, null is usually considered to be the only member of its free type. It can represent that numbers, strings, and objects are "valueless". Most programming languages contain null like JavaScript, and you can be familiar with null or nil.
JavaScript also has a second value indicating the vacancy of the value. Used to represent deeper "null values". It is a value of a variable. Indicates that the variable has not been initialized. If you want to query the value of an object attribute or array element, it returns undefined, it means that the attribute or element does not exist. undefined is a predefined global variable (it is different from null, it is not a keyword), and its value is undefined. If you use typeof to test the undefined type, "undefined" is returned, indicating that the value is the only member of the type.
Although null and undefined are different, they both represent "vacancies of values", and the two are often interchangeable. The operator that judges equality "==" thinks that the two are equal (use the strict equality operator "===" to distinguish them). Where the value is expected to be of a Boolean type, their values are all false. Similar to false. Both null and undefined do not contain any properties and methods. In fact, using "." and "[]" to access members or methods of these two values will produce a type error.
You might think that undefined represents system-level, unexpectedly living vacancies of wrong values, while null represents program-level, normal or expected vacancies of values. If you want to copy them to variables or properties, or pass them as parameters into a function, null is the best choice.
5. Global Objects
The previous sections discuss the element types and original values of javascript. Object types - objects, arrays and functions / But there is a very important class of objects that must not be clear now: global objects
Global object has important uses in JavaScript. The properties of a global object are symbols defined globally. JavaScript programs can be used directly. When the javascript interpreter starts, it creates a new global object and gives it a set of defined initial properties.
Global properties such as undefined Infinty and NaN
Global functions such as isNaN(), parseInt() and eval()
Constructors such as Date(), RegExp(), String(), Object(), and Array()
Global objects, such as Math and JSON
The initial attribute of a global object is not a reserved word, but they should be treated as a reserved word.
At the top level of the code - JavaScript code not within any function, you can refer to the global object through the javascript keyword.
var global = this; //Define a global variable that references a global object.
In client javascript, the window object acts as a global object. This global window object has a familiar window reference itself. It can replace this to refer to the global object. Windows defines global core attributes. However, some other global attributes are defined for web browsers and interactive javascript.
When created for the first time, the global object defines all predefined global values in JavaScript, and this special object also contains the global values defined for the program. If the code declares a global variable. This global variable is an attribute of the global object.
6. Packaging object
A javascript object is a compound value: it is a collection of attributes or named values. The attribute value is referenced through "." When the attribute value is a function, it is a method and uses om() to transfer the methods in object o.
We see that strings also have properties and methods.
The code copy is as follows:
var s ="hello world";
var word = s.substring(s.indexOf("")+1,s.length);//Use the attributes of the string.
document.write(word) //"ello world"
Since a string is not an object, why does it have properties? As long as the attribute of string s is referenced, javascript will convert the value of the string into an object by calling new String(s), which inherits the string method. and is used to process attribute references. Once the new attribute is referenced. Once the reference is finished, the newly created object will be destroyed. (This temporary object does not actually necessarily create or destroy, but this process looks like this.)
Like strings, numbers and boolean values also have their own methods, creating a temporary object through the Number() and Boolean() constructors. All of these methods are called from this temporary object. (null and undefined have not been wrapped objects, accessing their properties will have a type error)
Look at the following code and think about their execution process
The code copy is as follows:
var s = "test";
s.len = 4; //Set a property for it
var t = s.len //Find this property
When running this code, the value of t is undefined. The second line of code creates a temporary string object and gives len a value of 4. The object is then destroyed. The third line uses the original (not modified) string to create a new string object and tries to read the attributes of len.
This property does not exist naturally, indicating that the result is undefined. This code shows that when reading the property values (or methods) of strings, arrays, and boolean values, it behaves like an object, but if you try to assign a value to its property. This operation will be ignored; the modification only happens to temporary objects. This temporary object was not retained.
It should be noted that the creation of wrapper objects can be displayed through the String(), Number(), and Boolean() constructors:
The code copy is as follows:
var s = "test",
n = 1,
b = true;
var S = new String(s);
var N = new Number(n);
var B = new Boolean(b);
JavaScript converts the wrapper to the original value when necessary, so the object SNB in the previous code often - but not always - represents the same value as snb, "==" equal to the operator treats the original value and its wrapper object as equal.
But the "==="full operator treats them as inequality, and the difference between the original value and the object it wraps can be seen through the typeof operator.
7. Immutable original values and mutable object references.
The original value of javascript (undefined null boolean numbers and strings) is fundamentally different from objects (including arrays and functions). The original value is unchangeable; no method can (or mutate) a primitive value. It's obviously true for numbers and booleans - changing the value of a number doesn't make sense in itself, but it's not so obvious for strings, because strings appear to be an array of characters. We expect that characters in the string can be modified by the specified index. In fact, javascript prohibits doing this. All methods in the string appear to return a modified string, which is actually a new string.
The code copy is as follows:
var s = "hello world";
s.toUpperCase(); //Return "HELLO WORLD" and does not change the value of s
s //=> "hello world" original string has not changed
The comparison of the original values is the comparison of values, and they are only equal when their values are equivalent. This sounds a bit difficult for numbers, booleans, null and undefined, and there is no other way to compare them. Again, it is less obvious for strings; if two separate strings are compared, javascript considers equality if and only if their lengths are equal and the characters for each index are equal.
The code copy is as follows:
var o = {x:1} //Define an object
ox = 2 //Change the object by modifying the object's properties
oy = 3 //Change this object again and add a new property to it
var a =[1,2,3] //Arrays can also be modified
a[0]=0; //Change an element in the array
a[3]=4; Add a new element to the array
Object comparison is not value comparison: even if two objects contain the same attribute and the same value, they are not equal, and two arrays whose index elements are exactly equal are not equal.
The code copy is as follows:
var o ={x:1}, p={x:1}//Two two objects with the same attribute
o === p ;//=>false Two separate objects are never equal ( o == p ; =>false)
var a =[],b=[]; //Two separate empty arrays
a === b ; //=>false Two separate arrays are never equal
We usually call objects reference types to distinguish them from the basic types of JavaScript. According to the terminology, objects are references, and comparisons of objects are reference comparisons; they are equal when and when they apply the same base object.
The code copy is as follows:
var a = []; //Define a variable a that references an empty array
var b = a; //Variable b refers to the same array
b[0] = 1;
a[0] //=>1 Variable a will also be modified
a === b //=>true a and b refer to the same array, so they are equal.
Just like the code you just saw above, assigning an object (or array) to a variable, it is just a reference value of the assignment: the object itself is not copied once.
If you want to get a copy of an object or array, you must explicitly copy every attribute of the object or every element of the array. The following example is to copy the array through a loop.
The code copy is as follows:
var a = ['a', 'b', 'c']; //Array to be copied
var b = []; //Copy to the empty array of target
for (var i = 0; i < a.length; i++) { //Transtraighten each element in a[]
b[i] = a[i]; //Copy the element into b.
}
Similarly, if we want to compare two individual or arrays, we have to compare their properties or elements. The following code defines a function that compares array training.
The code copy is as follows:
function equalArrays(a, b) {
if (a.length != b.length) return false; //Two arrays with different lengths are not equal.
for (var i = 0; i < a.length; i++) //Loop through all elements
if (a[i] !== b[i]) return false; //If any elements are not equal, the array is not equal
return true; // Otherwise they are equal
}
8. Type conversion
The value type in javascript is very flexible, and we have seen this from boolean values: when javascript expects to use a boolean value, you can provide any type of value. JavaScript will convert the type itself as needed. Some values (true) are true, others (false) are converted to false. This also applies to other types. If javascript expects to use a string, it converts the given value into a string. If javascript expects to use an array, it converts the given value to a number (returns NaN if the conversion result is meaningless), some examples are as follows:
The code copy is as follows:
10 + "object" //=> "10object";
"7" * "4" // =>28 Both strings are converted into numbers
var n = 1 - "x" // =>NaN string x cannot be converted to a number
n + " objects" // =>"NaN objects":NaN转换为字符串"NaN"
下表说明了在javascript中如何进行类型转化。粗体突出了那些让你倍感意外的类型转化。空单元格表示不必要也没有执行的转换。
| value | 转换为字符串 | number | 布尔值 | Object |
| undefined null | "undefined" "null" | NaN 0 | false false | throws TypeError throws TypeError |
| true false | "ture" "false" | 1 0 | new Boolean(true) new Boolean(false) | |
| ""(空字符串) "1.2"(非空,数字) "one"(非空,非数字) | 0 1.2 NaN | false true true | new String("") new String("1.2") new String("one") | |
| 0 -0 NaN Infinty -Infinty 1(无穷大,非零) | "0" "0" "NaN" "Infinity" "-Infinity" "1" | false false false true true true | new Number(0); new Number(-0); new Number(NaN) new Number(Infinty) new Number(-Infinty) new Number(1) | |
| {}(任意对象) [](任意数组) [9](1个数字元素) ['a'](其它数组) function(){}(任意函数) | 参考本小节第三节内容 "" "9" 使用join()方法 参考本小节第三节内容 | 参考本小节第三节内容 0 9 NaN NaN | true true true true true |
上表提到的原始值到原始值的转换行对简单,我们已经在第本文第三小节讨论过转换为布尔值的情况了。所有原始值转换为字符串的情形也已经明确定义。转换为数字的情形比较微妙。那些以数字表示的字符串可以直接转化为数字,也允许在开始和结尾处带有空格。但在开始和结尾处的任意非空字符都不会被当成数字量的一部分,进而造成字符串为数字的结果为NaN。有一些数字转换看起来让人奇怪:true转换为1,false、空字符串""转换为0.
原始值到对象的转换也非常简单,原始值通过调用String(),Number()或Boolean()构造函数,转化为它们各自的包装对象。见本文第6节。
null和undefined属于例外,当将它们用在期望是一个对象的地方都会造成一个类型错误(TypeError)异常。而不会执行正常的转换。
对象到原始值的转换多少有些复杂,本小节第三小节有专门描述。
i.转换和相等性
由于javascript可以做灵活的类型转换,因此其“==”相等运算符也随相等的含义灵活多变。例如:如下这些比较结果均是true;
null == undefined //这两值被认为相等
"0" == 0 //在比较之前,字符串转换成数字。
0 = false //在这之前布尔值转换成数字。
"0" ==false //在比较之前字符串和布尔值都转换成数字
在第四章9节第一小节相信讲解了“==”等于运算符在判断两个值是否相等时做了那些类型转换,并同样介绍了“===”恒等运算符在判断相等时并未做任何的类型转换。
需要特别注意的是:一个值转换为另一个值并不意味着两个值相等。比如在期望使用布尔值的地方使用了undefined,将会转换为false,但这不表明undefined==false。javascript运算符和语句期望使用多样化的数据类型,并可以互相转换。if语句将undefined转化为false,但“==”运算符从不试图将其转化为布尔值。
ii.显式类型转化
尽管javascript可以做做很多类型转换,但有时仍需要做显式转换,或者为了使代码变得清晰易读而做显式转换。
做显式转换最重简单的方法就是使用Boolean()、Number()、String()或Object函数。我们在本文第6节已经介绍过了. 当不通过new运算符调运这些函数时,他们会作为类型转换函数并按照上边表格所描述的规则做类型转换。
复制代码代码如下:
Number("3") //=>3
String(false) //=>"false"或使用false.toString()
Boolean([]) //=>true
Object(3) // =>new Number(3)
需要注意的是,除了null或undefined之外的任何值都具有toString()方法,在这个方法的执行结果通常和String()方法返回的结果一致。同样需要注意的话,如果试图把null或undefined转化为对象。则会抛出一个类型错误typeerro。Object()函数在这种情况下不会抛出异常:它仅简单返回一个新创建的空对象。
javascript中的某些运算符会做隐式的类型转换,有时用于类型转换。如果“+”运算符的一个操作数是字符串,它将会把令一个操作数转换为字符串。一元“+”运算符将其操作数转换为数字。同样,一元“!”运算符将其操作数转换为布尔值取反,在代码中常会看到这种类型转换的惯用法。
复制代码代码如下:
x + "" // 等于字符串String(x)
+x //等价于Number(x),也可以写成x-0
!!x //等价于Boolean(x)
在计算机中数字的解析和格式化代码是非常普通的工作。javascript中提供了专门的函数和方法用来更加精确的数字到字符串(number-to-string)和字符串到数字(string-to-number)的抓换。
Nmuber类定义的toString()方法可以接收表示基数(二进制,八进制,十六进制等)的可选参数,如果不指定该参数,转化规则将是十进制。同样也可以将数字转换为其它进制数。(范围在2-36之间)
复制代码代码如下:
var n = 17;
b_string = n.toString(2); //转化为10001
o_string = "0" + n.toString(8); //转化为八进制021
hex_string = "0x" + n.toString(16); //转化为16进制0x11
javascript为控制输出中小数点位置和有效数字位数,或者决定是否需要指定指数计数法。Number类为这种数字到字符串定义了三个方法。
toFixed()根据小数点后指定位数,将数字转换为字符串,它从不使用指数计数法。toExponential()使用指数计数法,将数字转换为指数形式的字符串,其中小数点前只有一位,小数点后的位置则由参数指定(也就是说有效数字位数要比指定的位数多一位)。toPrecision()根据指定的有效数字位数,将数字转换为字符串。如果有效数字的位数小于数字整数部分的位数,则转换成指数形式。我们注意到,三个方法都会适当的进行四舍五入或填充0,
复制代码代码如下:
var n = 123456.789;
n.toFixed(0); //"123457"
n.toFixed(2); //"123456.79"
n.toFixed(5); //"123456.78900"
n.toExponential(1); //"1.2e+5"
n.toExponential(3); //"1.235e+5"
n.toPrecision(4); // "1.235e+5"
n.toPrecision(7); //"123456.8"
n.toPrecision(10); //"123456.7890"
如果通过Number()转换函数传入一个字符串,它会试图将其转化为一个整数或浮点数直接量,这个方法只能基于十进制进行转换,并且不能出现非法的尾随字符。parseInt()和parseFloat()函数(它们是全局函数,不属于人和类的方法),更加灵活。parseInt()只解析整数。而parseFloat()则可以解析整数和浮点数。如果字符串前边是0x或0X,parseInt()将其解析为16进制数。两个方法都会跳过任意量的前导空格,尽可能解析更多数值字符。并忽略后边的内容。如果第一个是非法的数字直接量,则返回NaN
复制代码代码如下:
parseInt("3many nice") //=>3;
parseFloat("3.14meters") //=>3.14
parseInt("-12.34") //=>-12
parseInt("0xff") //=>255
parseInt("-0XFF") //=>-255
parseFloat(".1") // =>0.1
parseInt("0.1") //=> 0
parseInt(".1") //=>NaN 不能以.开始
parseInt("$112") //=>NaN 不能以$开头
parseInt()可以接收第二个可选参数。这个参数指定数字转换的基数。合法的取值范围是2-36
复制代码代码如下:
parseInt("11", 2) //=>3(1*2+1)
parseInt("ff", 16) //=> 255(15*16 +15)
parseInt("zz", 36) //=>1295(35*36+35)
parseInt("077", 8) // 63(7*8 +7)
parseInt("077", 10) //77(7*10+7)
iii.对象转化为原始值。
对象到布尔值的转换非常简单:所有的对象(包括数组和函数)都转换为true。对于包装对象亦是如此,new Boolean(false)是一个对象而不是原始值,它将转换为true。 对象到字符串(object-to-String)和对象到数字(object-to-number)的转换是通过调用带转换对象的一个方法来完成的。一个麻烦的事实是,javascript对象有两个不同的方法来执行转换,并且接下来要讨论并且接下来要讨论的场景更加复杂。值得注意的是,这里提到的字符串和数字的转换规则只适用于本地对象(native fangf object).宿主对象(例如:由web浏览器定义的对象),根据各自的算法可以转换成字符串和数字。
所有的对象继承了两个转换方法。第一个是toString(), 它的作用是返回一个反映这个对象的字符串。默认的toString()方法并不会返回一个有趣的值。
({x:1,y:2}).toString() //=>"[object object]"
很多类定义了更多特定版本的toString()方法.
例如:数组类(Array class)的toString()方法将每个数组元素转换为一个字符串,并在元素之间添加逗号后并合成结果字符串。
函数类(Function class)的toString()方法返回这个函数的实现定义的表示方式。实际上,这里的实现方式是通常是将用户定义函数转换为javascript源代码字符串。
日期类(Date class)定义toString()方法返回一个可读的(可被javascript-parsable解析的)日期和事件字符串
RegExp class定义的toString()方法将RegExp对象转换为正则表达式直接量字符串。
复制代码代码如下:
[1, 2, 3].toString(); //=> "1,2,3"
(function(x) {f(x);}).toString(); // =>"function(x){/nf(x); /n}"
//d+/g.toString(); //=> ///d+/g
new Date(2015, 0, 1).toString() //=>Thu Jan 01 2015 00:00:00 GMT+0800 (中国标准时间)
另外一个函数是valueOf(),这个方法的任务并未详细定义:如果存在任意原始值,它就默认将对象转换为表示它的原始值。对象是复合值,而且大多数对象无法真正表示一个原始值,数组、函数和正则表达式简单地继承了这个默认方法,调用这些类型的实例的的valueOf()方法简单地返回对象本身。日期类定义的valueOf()方法返回它的一个内部表示:1970年1月1日以来的毫秒数。
复制代码代码如下:
var d = new Date(2015, 0, 1); //=>Thu Jan 01 2015 00:00:00 GMT+0800 (中国标准时间)
d.valueOf() //=>1420041600000
通过是用我们刚才讲解过的toString()和valueOf()方法,就可以做到对象到字符串和对象到数字的转换了。但在某些场景中,javascript执行了完全不同的对象到原始值的转换。这些特殊的场景在本节的最后会讲到。
javascript对象到字符串的转换经过了如下这些步奏
如果对象具有toString()方法,则调用这个方法。如果它返回一个原始值,javascript将这个值转换为字符串(如果本身不是字符串的话),并返回这个字符串结果。
如果对象没toString()方法,或者这个方法并不返回一个原始值,那么javascript会调用valueOf()方法。如果存在这个方法,则javascript调用它。如果返回值是原始值,javascript将责怪值转换为字符串。
9.变量声明。
在javascript程序中,使用一个变量之前应该先声明,变量是通过var来声明的,如下所示:
var i;
var sum;
也可以通过一个var关键字声明多个变量
var i,sun;
而且还可以将变量的初始值和变量声明和写在一起;
var message = "hello";
var i=0 ,j=0,k=0;
如果在var声明语句中给变量指定初始值,那么虽然声明了这个变量,但在给它存入一个值前,它的初始值是undefined. 我们注意到,在for和fo/in循环中同样可以使用var语句,这样可以更加简洁地声明在循环体语法中内使用的循环变量。 For example:
复制代码代码如下:
for (var i = 0; i < 10; i++) log(i);
for (var i = 0, j = 10; i < 10, j = 100; i++, j--) console.log(i * j)
for (var p in o) console.log(p);
如果在var声明语句中给变量指定初始值,那么虽然声明了这个变量,但在给它存入一个值前,它的初始值是undefined. 我们注意到,在for和fo/in循环中同样可以使用var语句,这样可以更加简洁地声明在循环体语法中内使用的循环变量。 For example:
复制代码代码如下:
var i=10;
i="ten";
10.变量作用域
一个变量的左右域(scope)是程序源代码中定义这个变量的区域,全局变量拥有全局作用域,在javascript代码中的任何地方都是定义。然而在函数内部声明变量只在函数体内有定义。他们是局部变量,作用是局部性的。函数参数也是局部变量,它们只在函数体内有定义。
在函数体内,局部变量的优先级高于同名的全局变量。如果在函数内声明一个局部变量或者函数参数中带有的变量和全局变量重名,那么全局变量就被局部变量所遮盖。
复制代码代码如下:
var scope = "global"; //声明一个全局变量
function checkscope() {
var scope = "local"; //声明一个同名的局部变量
return scope;
}
checkscope(); //=>"local"
尽管在全局作用域编写代码时可以不写var语句,但声明局部变量时则必须使用var语句。
复制代码代码如下:
scope = "global"; //声明一个全局变量,甚至不使用var来声明
function checkscope2() {
scope = "local"; //修改了全局变量
myscope = "local"; //这里显示式得声明了一个新的全局变量
return [scope, myscope]; //
}
checkscope2(); //=> ["local","local"]:产生了副作用
scope // =>"local"全局变量修改了
myscope //=> "local"全局命名空间搞乱了。
函数定义是可以嵌套的。由于每个函数都有它直接的作用域,因此会出现几个局部作用域嵌套的情况。
复制代码代码如下:
var scope = "global scope"; //全局变量
function checkscope() {
var scope = "local scope"; //局部变量
function nested() {
var scope = "sested scope"; //嵌套作用域内的局部变量
return scope;
}
return nested();
}
checkscope() //=>"嵌套作用域" sested scope
i.函数作用域和声明提前
在一些类似c语言的编程语言中,花括号内的每一段代码都具有各自的左右域,而且变量在声明他们的代码之外是不可见的我们称之为块级作用域(block scope),而javascript中没有块级作用域,javascript取而代之的使用了函数作用域(function scope);变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有意义的。
如下代码,在不同的位置定义了ijk,他们都在同一个作用域内,这三个变量在函数体内均有定义的。
复制代码代码如下:
function test(o) {
var i = 0; //i在整个函数体内均是定义的
if (typeif o == "object") {
var j = 0; //j在函数体内是有定义的,不仅仅是在这个代码段内
for (var k = 0; k < 10; k++) { //k在函数体内是有定义的,不仅仅是在循环内
console.log(k); //输出数字0-9
}
console.log(k); //k已经定义,输出10
}
console.log(j); //j已经定义了,但可能没有初始化。
}
javascript的函数作用域是指在函数内声明的所有变量在函数体内始终是可见的。有意思的是,这意味这变量在声明之前甚至已经可用。javascript的这个特性被非正式的称为声明提前(hoisting),即javascript函数里声明的所有变量(但不涉及赋值)都被提前至函数整体的顶部。如下代码:
复制代码代码如下:
var scope = "global";
function f() {
console.log(scope); //输出"undefined",而不是"global"
var scope = "local"; //变量在这里赋初始值,但变量本身在函数体内任何地方都是有定义的
console.log(scope); //输出"local"
你可能误以为函数的第一行会输出"global",因为代码还没有执行到var语句声明局部变量的地方。其实不然,由于函数作用域的特性模具部变量在整个函数体内始终有定义的,也就是说,在函数体内局部变量覆盖了同名全局变量。尽管如此,只有在程序执行到var语句的时候,局部变量才能正真的被赋值。
因此,上述的过程等价于:将函数内的变量声明"提前"至函数顶部,同时变量初始化留在原来的位置:
复制代码代码如下:
function f() {
var scope; //在函数的顶部声明了局部变量
console.log(scope); //变量存在,但其值是"undefined"
scope = "local"; //在这里将其初始化,并赋值
console.log(scope); //这里它具有了我们所期望的值
}
在具有块级作用域的编程语言中,在狭小的作用域里让变量声明和使用变量的代码尽可能靠近彼此,通常来说,这是一个非常不错的编程习惯。由于在javascript中没有块级作用域,因此一些程序员特意将变量声明放在函数体顶部,而不是将声明放在靠近使用变量之处。这种做法使得他们的源代码非常清晰地反映了真实的变量作用域。
ii作为属性的变量
当声明一个javascript全局变量时面试及上是定义了全局对象的一个属性。见本文第三节。
当使用var声明一个变量时,创建的这个属性是不可配置的。见第六章第7节。也就是说这个变量无法通过delete运算符删除。可能你已经注意到了,如果你没有使用严格模式并给一个未声明的变量赋值的话。javascript会自动创建一个全局变量。以这种方式创建变量是全局对象正常的可配置属性。可以删除它们。
复制代码代码如下:
var truevar = 1; //声明一耳光不可删除的全局变量
fakevar = 2; //创建全局对象的一个可删除的属性
this.fakevar2 = 3; //同上
delete truevar // =>false 变量并没有删除
delete fakevar //=>true 变量被删除
delete this.fakevar2 //=>true 变量被删除
javascript全局变量是全局对象的属性,这是在ECMAScript规范中强制规定的。对于局部变量则没有此规定,但我们可以想象得到,局部变量当做跟函数调用相关的某个对象的属性。ECMAScript3规范称对象为“调用对象”(call object),ECMAScript5规定范称为“声明上下文对象”(declarative environment record)。javascript可以允许使用this关键字引用全局对象,却没有方法可以引用局部变量中存放的对象。这种存放局部变量的对象的特有性质,是一种对我们不可见的内部实现。然而,这些局部变量对象存在的观念是非常重要的。
iii作用域链
javascript是基于词法作用域的语言:通过阅读包含变量定义在内的舒航源码就能知道变量的作用域。
全局变量在程序中始终是都是有定义的。局部变量在声明它的函数体内以及其所嵌套的函数内始终是有定义的。