语法和数据类型
1.There are three kinds of declaration in JavaScript
var
Declares a variable, optionally initializing it to a value.
let
Declares a block-scoped, local variable, optionally initializing it to a value.
const
Declares a block-scoped, read-only named constant.
By simply assigning it a value. For example, x = 42. This always declares a global variable, if it is declared outside of any function. It generates a strict JavaScript warning. You shouldn't use this variant.
A variable declared using the var or let statement with no assigned value specified has the value of undefined
.
The undefined value behaves as false when used in a boolean context.
The undefined value converts to NaN when used in numeric context.
When you evaluate a null
variable, the null value behaves as 0 in numeric contexts and as false in boolean contexts.
试图访问一个未声明的变量或者访问一个使用 let 声明的但未初始化的变量会导致一个 ReferenceError 异常被抛出。
4.Variable hoisting
JavaScript 变量的另一特别之处是,你可以引用稍后声明的变量而不会引发异常。这一概念称为变量声明提升(hoisting);JavaScript 变量感觉上是被“提升”或移到了所有函数和语句之前。然而提升后的变量将返回 undefined 值。所以在使用或引用某个变量之后进行声明和初始化操作,这个被提升的引用仍将得到 undefined 值。
/**
* Example 1
*/
console.log(x === undefined); // logs "true"
var x = 3;
/**
* Example 2
*/
// will return a value of undefined
var myvar = "my value";
(function() {
console.log(myvar); // undefined,其实后面的 myvar有没有声明都返回 undefined
var myvar = "local value";
})();
/**
* Example 1
*/
var x;
console.log(x === undefined); // logs "true"
x = 3;
/**
* Example 2
*/
var myvar = "my value";
(function() {
var myvar;
console.log(myvar); // undefined
myvar = "local value";
})();
在 ECMAScript 2015 中,let(const)将不会提升变量到代码块的顶部。因此,在变量声明之前引用这个变量,将抛出错误ReferenceError
。这个变量将从代码块一开始的时候就处在一个“暂时性死区”,直到这个变量被声明为止。
console.log(x); // ReferenceError
let x = 3;
5.函数提升(Function hoisting)
对于函数,只有函数声明会被提升到顶部,而不包括函数表达式。
/* 函数声明 */
foo(); // "bar"
function foo() {
console.log("bar");
}
/* 函数表达式 表达式定义的函数,称为匿名函数。匿名函数没有函数提升。*/
baz(); // TypeError: baz is not a function
//此时的"baz"相当于一个声明的变量,类型为undefined。
由于baz只是相当于一个变量,因此浏览器认为"baz()"不是一个函数。
var baz = function() {
console.log("bar2");
};
6.数据结构和类型
六种 原型 数据类型:
Boolean. 布尔值,true 和 false
.
null. 一个表明 null 值的特殊关键字。 JavaScript 是大小写敏感的,因此 null
与Null、NULL或其他变量完全不同。
undefined. 变量未定义时的属性。
Number. 表示数字,例如: 42 或者 3.14159。
String. 表示字符串,例如:"Howdy"
Symbol ( 在 ECMAScript 6 中新添加的类型).。一种数据类型,它的实例是唯一且不可改变的。
以及 Object 对象
Objects 和 functions 是本语言的其他两个基本要素。你可以将对象视为存放值的命名容器,而将函数视为你的应用程序能够执行的过程(procedures)。
7.数据类型的转换
字符串转换为数字(converting strings to numbers)
parseInt()和parseFloat()
参见:parseInt()和parseFloat()的相关页面。
parseInt 仅能够返回整数,所以使用它会丢失小数部分。另外,调用 parseInt 时最好总是带上进制(radix) 参数,这个参数用于指定使用哪一种进制。
单目加法运算符
将字符串转换为数字的另一种方法是使用单目加法运算符。
"1.1" + "1.1" = "1.11.1"
(+"1.1") + (+"1.1") = 2.2 // 注:加入括号为清楚起见,不是必需的。
8.字面量
在JavaScript中,你可以使用各种字面量。这些字面量是脚本中按字面意思给出的固定的值,而不是变量。(译注:字面量是常量,其值是固定的,而且在程序脚本运行中不可更改,比如false,3.1415,thisIsStringOfHelloworld ,invokedFunction:myFunction("myArgument")。
数组字面量 (Array literals)
var coffees = ["French Roast", "Colombian", "Kona"];
var a=[3];
console.log(a.length); // 1
console.log(a[0]); // 3
如果你在元素列表的尾部添加了一个逗号,它将会被忽略。在下面的例子中,数组的长度是3,并不存在myList[3]这个元素。
var myList = ['home', , 'school', ];
整数
整数 (Intergers)
(译注:原文如此,没写成“整数字面量”,这里指的是整数字面量。)
整数可以用十进制(基数为10)、十六进制(基数为16)、八进制(基数为8)以及二进制(基数为2)表示。
十进制整数字面量由一串数字序列组成,且没有前缀0。
八进制的整数以 0(或0O、0o)开头,只能包括数字0-7。
十六进制整数以0x(或0X)开头,可以包含数字(0-9)和字母 a~f 或 A~F。
二进制整数以0b(或0B)开头,只能包含数字0和1。
严格模式下,八进制整数字面量必须以0o或0O开头,而不能以0开头。
0, 117 and -345 (十进制, 基数为10)
015, 0001 and -0o77 (八进制, 基数为8)
0x1123, 0x00111 and -0xF1A7 (十六进制, 基数为16或"hex")
0b11, 0b0011 and -0b11 (二进制, 基数为2)
对象字面量 (Object literals)
对象属性名字可以是任意字符串,包括空串。如果对象属性名字不是合法的javascript标识符,它必须用""包裹。属性的名字不合法,那么便不能用.访问属性值,而是通过类数组标记("[]")访问和赋值。
var unusualPropertyNames = {
"": "An empty string",
"!": "Bang!"
}
console.log(unusualPropertyNames.""); // 语法错误: Unexpected string
console.log(unusualPropertyNames[""]); // An empty string
console.log(unusualPropertyNames.!); // 语法错误: Unexpected token !
console.log(unusualPropertyNames["!"]); // Bang!
var foo = {a: "alpha", 2: "two"};
console.log(foo.a); // alpha
console.log(foo[2]); // two
//console.log(foo.2); // Error: missing ) after argument list
//console.log(foo[a]); // Error: a is not defined
console.log(foo["a"]); // alpha
console.log(foo["2"]); // two
流程控制与错误处理
1.语句块
注意:在ECMAScript 6标准之前,Javascript没有块作用域。如果你在块的外部声明了一个变量,然后在块中声明了一个相同变量名的变量,并赋予不同的值。那么在程序执行中将会使用块中的值,这样做虽然是合法的,但是这不同于JAVA与C。示例:
var x = 1;{ var x = 2;}alert(x); // 输出的结果为 2
这段代码的输出是2,这是因为块级作用域中的 var x变量声明与之前的声明在同一个作用域内。在C语言或是Java语言中,同样的代码输出的结果是1。
从 ECMAScript 2015 开始,使用 let 定义的变量是块作用域的。 参阅 let
。
2.条件判断语句
不建议在条件表达式中使用赋值操作,因为在快速查阅代码时容易看成等值比较。不要使用下面的代码:
if (x = y) {
/* do the right thing */
}
如果你需要在条件表达式中使用赋值,通常在赋值语句前后额外添加一对括号。例如:
if ((x = y)) {
/* do the right thing */
}
False 等效值
下面这些值将被计算出 false (also known as Falsy values):
false
undefined
null
0
NaN
空字符串 ("")
当传递给条件语句时,所有其他值,包括所有对象会被计算为 true 。
请不要混淆原始的布尔值true和false 与 布尔对象的值true和false(译者注:下例中b属于对象,会被计算为true!)。例如:
var b = new Boolean(false);
if (b) // this condition evaluates to true
if (b == true) // this condition evaluates to false
3.循环语句
标签语句(label Statement)
标签语句提供一种使你同一程序的在另一处找到它的标识。例如,你可以用一个标签来识别一个循环,并用break或continue语句来说明一个程序是否要中断这个循环或是继续执行。如下所示:
label :
statement
label 的值可以是js的任何非保留字标识符。 用label 标识的语句可以是任何语句。
例如
在这个示例中,markLoop这个标签定义了一个while循环。
markLoop:
while (theMark == true) {
doSomething();
}
使用中断语句终止循环、开关或与标签语句连接。
当你使用没有带标签语句的中断语句(break)时,while,do-while,for或者switch封闭的内部语句将立即终止,并转移到后面的语句执行。
当你使用带有标签语句的中断语句(break)时,将终止在特定的标签语句。
对象操作语句
for...in
语句迭代一个指定的变量去遍历这个对象的属性,每个属性,javascript 执行指定的语句。
数组(Arrays)虽然大多趋向于用for...in作为一种遍历数组(Array)元素的方式,因为除了遍历数组元素,for...in语句也遍历了用户自定义属性。如果你修改了数组对象,比如添加了通用属性或者方法,for...in语句还会返回除了数字索引(index)外的自定义属性的名称(name)。因此还是用带有数字索引的传统for循环来遍历数组会比较好。
for each...in
是一种在 JavaScript 1.6介绍过的循环语句。它和for...in相似,但是让对象属性的值递回取得,而不是作用于它们的名字。(已经被废弃,但没有被删除)