语法综述
JavaScript程序一行一行地执行。一般情况下,每一行就是一个语句,语句以分号结尾,一个分号就表示一个语句结束。多个语句可以写在一行内。
var a = 1 + 2 ; var b = "abc";
分号前面可以没有任何内容,JavaScript引擎将其视为空语句。
; ; ; //表示三个空语句
分号表示一条语句的结尾。但是,有一些语法结构不需要在语句的结尾添加分号,主要是以下三种情况:
(1) for 和 while 语句
for(;;;){}
while(true){}
注意do…while 是有分号的。
(2) 分支语句 if ,switch ,try
if(true){}
switch{}
try {}
(3) 函数的声明语句
function f(){} //没有分号
var f = function f(){}; //函数表达式要有分号
以上三种情况使用分号也不会报错,js引擎会把这个分号解释成空语句。
变量
变量是对“值”的引用,使用变量等同于引用一个值。每一个变量都有一个变量名。如果只是声明变量而没有赋值,则该变量的值为undefined
var a ;
console.log(a);// undefined
使用var定义变量时会出现一个问题,变量提升。JavaScript引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果,就是所有的变量的声明语句,都会被提升到代码的头部,这就叫做变量提升。
console.log(a);
var a= 1;
上面代码首先使用console.log方法,在控制台(console)显示变量a的值。这时变量a还没有声明和赋值,所以这是一种错误的做法,但是实际上不会报错。因为存在变量提升,真正运行的是下面的代码:
var a;
console.log(a);
a = 1;
数据类型
最新的 ECMAScript 标准定义了 8 种数据类型,有 6 种原始类型和两个特殊值。
6 种原始类型分别是:
- 数值(Number)
- 字符串(String)
- 布尔(Boolean)
- 对象(Object)
- 数组(Array)
- 函数(Function)
2 个特殊值:
- Null
- Undefined
JavaScript使用 typeof 运算符 可以确定一个值到底是什么类型:
typeof 123; // "number"
typeof "123"; // "string"
typeof false; // "boolean"
typeof undefined; //"undefined"
function f(){};
typeof f; //"function"
//除了以上所有的都是object
typeof null; //"object"
typeof {}; //"object"
typeof []; //"object"
typeof window; //"object"
从上面代码可以看到,空数组([])的类型也是object,这表示在JavaScript内部,数组本质上只是一种特殊的对象。另外,null的类型也是object,这是由于历史原因造成的,为了兼容以前的代码,后来就没法修改了,并不是说null就属于对象,本质上null是一个类似于undefined的特殊值。既然typeof对数组(array)和对象(object)的显示结果都是object,那么怎么区分它们呢? instanceof 运算符可以做到。
var o = {};
var a = [];
o instanceof Array ; //false
a instanceof Array ; //true
instanceof 运算符 用来确定一个对象是否为某个构造函数的实例。
var v = new Vehicle();
v instanceof Vehicle
// true
instanceof运算符的左边放置对象,右边放置构造函数。在JavaScript之中,只要是对象,就有对应的构造函数。因此,instanceof运算符可以用来判断值的类型。
[1, 2, 3] instanceof Array // true
({}) instanceof Object // true
上面代码表示数组和对象则分别是Array对象和Object对象的实例。最后那一行的空对象外面,之所以要加括号,是因为如果不加,JavaScript引擎会把一对大括号解释为一个代码块,而不是一个对象,从而导致这一行代码被解释为“{}; instanceof Object”,引擎就会报错。需要注意的是,由于原始类型的值不是对象,所以不能使用instanceof运算符判断类型。
"" instanceof String // false
1 instanceof Number // false
上面代码中,字符串不是String对象的实例(因为字符串不是对象),数值1也不是Number对象的实例(因为数值1不是对象)。如果存在继承关系,也就是某个对象可能是多个构造函数的实例,那么instanceof运算符对这些构造函数都返回true。
var a = [];
a instanceof Array // true
a instanceof Object // true
上面代码表示,a是一个数组,所以它是Array的实例;同时,a也是一个对象,所以它也是Object的实例。
Null 和 Undefined
null与undefined都可以表示“无”,含义非常相似。将一个变量赋值为undefined或null,个人认为几乎没区别。
对于null和undefined,可以大致上像下面这样理解。
null表示”没有对象”,即该处不应该有值。典型用法是:
作为函数的参数,表示该函数的参数不是对象。
作为对象原型链的终点。
undefined表示”缺少值”,就是此处应该有一个值,但是还未定义。典型用法是:
- 变量被声明了,但没有赋值时,就等于undefined。
- 调用函数时,应该提供的参数没有提供,该参数等于undefined。
- 对象没有赋值的属性,该属性的值为undefined。
- 函数没有返回值时,默认返回undefined。
var i ;
i //undefined
function f(x){console.log(x)}
f() //undefined
var o = new object();
o.a //undefined
var x = f();
x //undefined
布尔值
JavaScript预期某个位置应该是布尔值,会将该位置上现有的值自动转为布尔值。转换规则是除了下面六个值被转为false,其他值都视为true。
- undefined
- null
- 0
- NaN
- false
- “”
需要特别注意的是,空字符串(“”)是false,但空数组([])和空对象({})对应的布尔值,都是true。
if([]){console.log(true)}
//true
if({}){console.log(true)}
//true