JavaScript Guide

语法和数据类型

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 对象

Objectsfunctions 是本语言的其他两个基本要素。你可以将对象视为存放值的命名容器,而将函数视为你的应用程序能够执行的过程(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相似,但是让对象属性的值递回取得,而不是作用于它们的名字。(已经被废弃,但没有被删除)

推荐阅读更多精彩内容