ES5

基础语法

注释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 这是单行注释

/*
这是
多行
注释
*/

//此外,由于历史上 JavaScript 可以兼容 HTML 代码的注释,所以<!--和-->也被视为合法的单行注释。
x = 1; <!-- x = 2;
--> x=3;y=4;
console.log(x);
//上面代码中,只有x = 1会执行,其他的部分都被注释掉了.
function countdown(n){
while (n --> 0) console.log(n);
}
countdown(3)
//上面代码中,n --> 0实际上会当作n-- > 0,因此输出2、1、0。

区块

JavaScript 使用大括号,将多个相关的语句组合在一起,称为“区块”(block)。
对于var命令来说,JavaScript 的区块不构成单独的作用域(scope)。
Es6里面let有作用域问题,var是全局。

1
2
3
4
5
{
var a = 1;
}

a // 1

条件语句

1
2
3
4
5
6
if(m === 3)
m = m + 1;
else
console.log(m)
//这种写法要求条件表达式后面只能有一个语句。

如果想执行多个语句,必须在if的条件判断之后,加上大括号,表示代码块(多个语句合并成一个语句)。

1
2
3
4
5
6
7
8
9
var x = 2;
var y = 2;
if (x < y) {
console.log(x);
}else if (x === 2){
console.log("elif",x)
}else {
console.log("else:",x)
}

switch结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function f(){
console.log('fffff')
}

var x = 2;
switch (x) {
case 1+1:
f();
break;
case 3:
console.log('x 等于3');
break;
default:
console.log("deault x")
}

三元运算符 ?:

JavaScript 还有一个三元运算符(即该运算符需要三个运算子)?:,也可以用于逻辑判断。
(条件) ? 表达式1 : 表达式2
上面代码中,如果“条件”为true,则返回“表达式1”的值,否则返回“表达式2”的值。
var even = (n % 2 === 0) ? true : false;
上面代码中,如果n可以被2整除,则even等于true,否则等于false。它等同于下面的形式。

1
2
3
4
5
6
var even;
if (n % 2 === 0) {
even = true;
} else {
even = false;
}

这个三元运算符可以被视为if...else...的简写形式,因此可以用于多种场合。

1
2
3
4
5
6
7
8
9
10
11
12
var myVar;
console.log(
myVar ?
'myVar has a value' :
'myVar does not have a value'
)
//myVar does not have a value

var n = 4;
var msg = '数字' + n + '是' + (n % 2 === 0 ? '偶数' : '奇数');
console.log(msg);
//数字4是偶数

循环语句

while循环

1
2
3
4
5
6
7
8
9
10
11
12
13
while (条件) {
语句;
}

var i = 0;
while (i < 10){
console.log('i 当前为:' + i);
i = i + 1;
}
//无限循环
while (true) {
console.log('Hello, world');
}

for循环

1
2
3
4
5
6
7
8
9
10
11
12
13
for (初始化表达式; 条件; 递增表达式)
语句

// 或者

for (初始化表达式; 条件; 递增表达式) {
语句
}

var x = 3;
for (var i = 0; i <= x; i++){
console.log(i);
}

上面代码中,初始化表达式是var i = 0,即初始化一个变量i;测试表达式是i < x,即只要i小于x,就会执行循环;递增表达式是i++,即每次循环结束后,i增大1。

所有for循环,都可以改写成while循环。上面的例子改为while循环,代码如下。

1
2
3
4
5
6
7
var x = 3;
var i = 0;

while (i < x) {
console.log(i);
i++;
}

do…while循环

do...while循环与while循环类似,唯一的区别就是先运行一次循环体,然后判断循环条件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
do
语句
while (条件);

// 或者
do {
语句
} while (条件);

var x = 3;
var i = 0;
do{
console.log(i);
i++;
}while (i < x);

break语句和continue语句

break语句和continue语句都具有跳转作用,可以让代码不按既有的顺序执行。

1
2
3
4
5
6
7
8
9
10
11
12
var i = 0;
while (i <100){
console.log(i)
i++;
if (i === 10) break;
}
//上面代码一旦i等于10,就会跳出循环

for (var i = 0; i < 5; i++){
if (i === 2) continue;
else console.log(i);
}

标签(label)

JavaScript 语言允许,语句的前面有标签(label),相当于定位符,用于跳转到程序的任意位置,标签的格式如下。
标签可以是任意的标识符,但不能是保留字,语句部分可以是任意语句。
标签通常与break语句和continue语句配合使用,跳出特定的循环。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
label:
语句

top:
for (var i = 0; i < 3; i++){
for (var j = 0; j < 3; j++){
if (i === 1 && j === 1) break top;
console.log('i=' + i + ', j=' + j);
}
}
// i=0, j=0
// i=0, j=1
// i=0, j=2
// i=1, j=0
//在break命令后加上top标签,满足条件时,直接跳出双层循环。
//如果break语句后面不使用标签,则只能跳出内层循环,进入下一次外层循环。

标签也可以用于跳出代码块。

1
2
3
4
5
6
7
8
9
foo: {
console.log(1);
break foo;
console.log('本行不会输出');
}
console.log(2);
// 1
// 2
//上面代码执行到break foo,就会跳出区块。

continue语句也可以与标签配合使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
top:
for (var i = 0; i < 3; i++){
for (var j = 0; j < 3; j++){
if (i === 1 && j === 1) continue top;
console.log('i=' + i + ', j=' + j);
}
}
// i=0, j=0
// i=0, j=1
// i=0, j=2
// i=1, j=0
// i=2, j=0
// i=2, j=1
// i=2, j=2

上面代码中,continue命令后面有一个标签名,满足条件时,会跳过当前循环,直接进入下一轮外层循环。如果continue语句后面不使用标签,则只能进入下一轮的内层循环。

数据类型

概述

# 简介

JavaScript的数据类型共有六种:
数值(number):整数和小数(比如13.14
字符串(string):文本(比如Hello World
布尔值(boolean):表示真伪的两个特殊值,即true(真)和false(假)
undefined:表示“未定义”或不存在,即由于目前没有定义,所以此处暂时没有任何值
null:表示空值,即此处的值为空。
对象(object):各种值组成的集合。

数值字符串布尔值这三种类型,合称为原始类型(primitive type)的值,即它们是最基本数据类型,不能再细分了。
对象则称为合成类型(complex type)的值,因为一个对象往往是多个原始类型的值的合成,可以看作是一个存放各种值容器
undefinednull,一般将它们看成两个特殊值
对象是最复杂的数据类型,又可以分成三个子类型:狭义的对象(object)数组(array)函数(function)
###typeof运算符
JavaScript 有三种方法确定一个值的类型:typeof运算符、instanceof运算符、Object.prototype.toString方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
console.log(typeof 123)
console.log(typeof "123")
console.log(typeof false)
console.log(typeof undefined)

var s;
console.log(typeof s)

function f(){}
console.log(typeof f)

console.log(typeof window)
console.log(typeof null)
console.log(typeof {})
console.log(typeof [])

//number
//string
//boolean
//undefined
//undefined
//function
//undefined
//object
//object
//object

instanceof运算符可以区分数组和对象。

1
2
3
4
5
6
7
var o = {};
var a = [];
console.log(o instanceof Array)
console.log(a instanceof Array)

//false
//true

##null, undefined 和布尔值
nullundefined都可以表示“没有”,含义非常相似。将一个变量赋值为undefined或null,老实说,语法效果几乎没区别。
if语句中,它们都会被自动转为false,相等运算符(==)甚至直接报告两者相等

1
2
3
4
5
6
7
8
9
10
11
if (!undefined){
console.log("undefined is false")
}
if (!null){
console.log("null is false")
}
console.log(undefined==null)

//undefined is false
//null is false
//true

undefinednull区别是:null是一个表示“空”的对象,转为数值时为0;undefined是一个表示”此处无定义”的原始值,转为数值时为NaN

数值

javascript内部所有数字都是64位浮点数,即1==1.0
数值

ES6

let命令

基础语法

1
2
3
4
5
6
7
8
//es6 新增了let命令,用法类似var,但let命令只在当前代码块内有效
//下面外部调用var正常调用,但let就无法调用不存在
{
let a = 10;
var b = 1;
}
console.log(a)
console.log(b)
1
2
3
4
5
6
7
8
9
//用var则是全局 则是10  而用let就是局部就是7
var a = [];
for (let i = 0; i < 10; i++){
console.log("外部",i);
a[i] = function () {
console.log(i);
}
}
a[7]();
1
2
3
4
5
6
7
8
9
//另外,for循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域
//而循环体内部是一个单独的子作用域。
for (let i = 0; i < 3; i++){
let i = 'abc';
console.log(i);
}
//abc
//abc
//abc

不存在变量提升

var命令会发生“变量提升”现象,即变量可以在声明之前使用,值为undefined。
为了纠正这种现象,let命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。

1
2
3
4
5
console.log(foo);//输出undefined
var foo = 2;

console.log(bar);//报错ReferenceError
let bar = 2;

暂时性死区

只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。

1
2
3
4
5
6
var tmp = 123;
if (true){
tmp = 'abc';
let tmp;
}