JavaScript高级程序设计第三版(第三章:JavaScript基本概念)

1、本章简介

本章主要按照第三版定义的ECMAScript介绍这门语言的基本概念,并就第五版的变化给出说明。javascript

2、语法

ECMA语法大量借鉴了C以及其余类C语言(如Java何Perl)的语法。java

2.一、区分大小写

ECMA中的一切(变量、函数名和操做符)都区分大小写。因此test和Test是两个不一样的变量。正则表达式

2.二、标识符

标识符就是指变量、函数、属性的名字,或者函数的参数。标识符按照如下规则组成的一个或多个字符。浏览器

  • 第一个字符必须是一个字母、下划线(—)或一个美圆符号($)。
  • 其余字符能够是字母、下划线、美圆符号或数字。
  • 定义变量尽可能使用驼峰大小写格式,和ECMAScript的内置函数和对象命名保持一致(firstSecond、myCar)。
  • 不能把关键字、保留字、true、false和null用做标识符。

2.三、注释

// ----> 单行注释
/**/ ----> 多行注释(块级注释).*号不是必须的,纯粹是为了提升注释的可读性.

2.四、严格模式

ECMAScript5引入了严格模式(strict mode)的概念。在严格模式下,ECMAScript3中的一些不肯定的行为将获得处理,且对某些不安全的操做也会抛出错误。要在整个脚本中启用严格模式。能够在顶部添加以下代码:安全

"use scrict";

它是一个编译指示,告诉JavaScript引擎切换到严格模式。函数

在函数内部的上方包含这条编译指示,也能够指定函数在严格模式下执行。以下代码:性能

function doSomething(){
	"use scrict"
	//函数体
}

严格模式下,JavaScript的执行结果会有很大不一样。支持严格模式的浏览器包括:IE10+、Firefox4+、Safari5.1+、Opera 12 + 和 Chrome。测试

2.五、语句

ECMAScript中的语句以一个分号结尾,虽然语句结尾分号不是必须的,建议任什么时候候都不要省略它。这样能够避免不少错误。this

代码行结尾处没有分号会致使压缩错误。spa

也能够提升性能,这样解析器就不用花时间推测应该在哪里插入分号了。以下代码:

var diff = 5 - 3;

条件控制语句在多条语句状况下才要求使用代码块。但建议始终在控制语句中使用代码块。由于这样可使代码更加清晰,也能下降出错概率。以下代码:

if(false){		
	alert(5);
}
if(false)	//有效,不推荐
    alert(6);

2.六、关键字和保留字

//ECMA-262的关键字:*号是第五版新增的关键字
break, do, instanceof, typeof, case, else, new, var, catch, finally, return, void,
continue, for, switch, while, debugger*, function, this, with, default, if, throw,
delete, in, try
	
//ECMA-262的保留字
abstract, enum, int, short, boolean, export, interface, static, byte, extends, long,
super, char, final, native, synchronized, class, float, package, throws, const, goto,
private, transient, debugger, implements, protected, volatile, double, import, public
	
//第五版非严格模式下运行时的保留字缩减为下列这些:
class, enum, extends, super, const, export, import
	
//第五版严格模式下运行时的保留字:
implements, package, public, interface, private, static, let, protected, yield
	
//ECMA-262第5版对eval和arguments还施加了限制。在严格模式下,这两个名字也不能做为标识符或属性名,不然抛出错误。

总之以上的保留字和关键字在开发的时候不要用就好了。

2.七、变量

ECMAScript的变量是松散类型的,能够用来保存任何类型的数据。每一个变量仅仅是一个用于保存值得占位符而已。

定义变量的时候要使用 var 操做符,后跟变量名。以下代码:

//以上定义了一个名为message的变量,该变量能够用来保存任何值。
//若是这样未通过初始化的变量,会保存一个特殊的值 ---> undefined
var message;
console.log(message);	//undefined

也能够直接初始化变量,在定义变量的同时就能够设置变量的值。以下代码:

var message = 'hi';

以上变量message保存了一个字符串值"hi",这样的初始化变量并不会把它一直标记为字符串类型,初始化类型就是给变量赋一个值那么简单。

所以,能够在修改变量值的同时修改值的类型。以下代码:

//代码一开始保存了一个字符串值"hi",而后值又被数字值100取代。
//这种操做在ECMAScript中彻底有效。
var message = 'hi';
message = 100;

使用 var 操做符定义的变量将成为定义该变量的做用域中的局部变量。也就是说,若是在函数中定义了一个 var 变量,那么这个变量在函数退出后就会被销毁。以下代码:

//这里,变量message是在函数中使用var定义的。当函数被调用时,就会建立该变量并为其赋值。
//在此以后,这个变量又会被当即销毁,所以,下一行代码就会致使错误。
function test(){
	var message = 'hi';	//局部变量
}
test();

alert(message);	//Uncaught ReferenceError:message is not defined(…)

能够在函数内部省略 var 操做符,从而建立一个全局变量。以下代码:

////能够在函数内部省略 var 操做符,在函数内部建立一个全局变量,这种方式是不推荐的。就是不要使用这种方式在函数内部定义变量。
function test(){
	message = 'hi';
}

alert(message);   //hi

能够用一条语句定义多个变量,用逗号分开便可,初始化或不初始化均可以。以下代码:

//因为ECMAScript是松散类型的,于是使用不一样类型初始化变量的操做是能够放在一条一语句中来完成。
var message = 'hi',
	found = false,
	age = 29;

3、数据类型

ECMAScriptt有五种简单的数据类型(也称为基本数据类型):Undefined、Null、Boolean、Number、String。还有一种复杂数据类型 -->Object。Object本质是由一组无须的名值对组成的。ECMAScript不支持任何建立自定义类型的机制。而全部值最终都是这6种数据类型之一。好像6种数据类型不足以表示全部数据。可是,因为ECMAScript数据类型具备动态性,所以没有必要再定义其余数据类型的必要了。

3.一、typeof 操做符

ECMAScript 是松散类型的,所以须要有一种手段检测给定变量的数据类型。typeof 就是负责提供这方面信息的操做符。对一个值使用 typeof 操做符可能返回下列某个字符串。

//对一个值使用typeof 操做符可能返回下列某个字符串。
'undefined'	    //若是这个值没有定义
'boolean'		//若是这个值是布尔值
'string'		//若是这个值是字符串		
'number'		//若是这个值是数值
'object'		//若是这个值是对象或null
'function'	    //若是这个值是函数

var mess = 'some string';

console.log(typeof mess);	//'string'
console.log(typeof(mess));	//'string'
console.log(typeof 95);		//'number'

typeof 操做符的操做数能够是变量,也能够是数值字面量。typeof是一个操做符而不是函数,上面例子中的圆括号可使用,但不是必须的。有些时候typeof 操做符会返回一些使人迷惑但技术上却正确的值。
好比:调用typeof null会返回 'object'。由于特殊值null被认为是一个空对象的引用。
Safari 5 以及以前版本,Chrome7以及以前版本对正则表达式调用 typeof 操做符会返回'function',而其余浏览器会返回 'object'
从技术角度讲,函数在ECMAScript中是对象,不是一种数据类型。然而,函数也确实有一些特殊的属性,所以经过typeof操做符来区分函数和其余对象是有必要的。

3.二、Undefined类型

Undefined类型只有一个值,即特殊的Undefined。在使用var声明变量但未对其加以初始化时,这个变量就是Undefined。

var message2;	//未经初始化的值默认值就是undefined
console.log(message2 == undefined);	//true


//不过包含undefined的值的变量与还没有定义的变量仍是不同的。
var message3;		//undefined
//下面这个变量并无声明
//var age;
console.log(message3);
//console.log(age);	//产生错误

//对于还没有声明过的变量,只能执行一项操做,即便用typeof操做符检测其数据类型
//(对未声明的变量调用delete不会致使错误,但这样作没什么实际意义,并且在严格模式下确实会致使错误)。


//使人困惑的是,对未初始化的变量执行typeof操做符会返回undefined值,而对未声明的变量执行typeof操做符也会返回undefined

var message4;
//下面这个变量并无声明
//var age;
console.log( typeof message4);//undefined
console.log( typeof age);//undefined

结果代表,对未初始化和未声明的变量执行typeof操做符都返回了undefined值。由于虽然两种变量从技术角度看有本质区别,但实际上不管哪一种变量也不可能执行真正的操做。对未初始化的变量会自动赋予undfined值,但显示的初始化变量依然是明智的选择。这样的话,那么当typeof操做符返回undefined值时,咱们就知道被检测的变量尚未被声明,而不是还没有初始化。

3.三、Null类型

null类型是第二个只有一个值的数据类型,这个特殊的值是null。从逻辑角度看,null值表示一个空对象指针。而这也正是使用 typeof 操做符检测null值会返回 'object'的缘由。

var car = null;
console.log(typeof car);	//'object'

//若是定义的变量准备在未来用于保存对象,那么最好将该变量初始化为null而不是其它值。
//这样,只要直接检查null值就能够知道相应的变量是否已经保存了一个对象引用:
if( car != null ){
	//TODO 对car对象进行操做
}


//实际上,undefined值是派生自null值的,所以ECMA-262规定对它们的相等性测试要返回true;
console.log(null == undefined);	//true

须要注意,这个操做符出于比较的目的会转换其操做数。尽管null和undefined有这样的关系,但它们用途不同。不管在什么状况下都没有必要把一个变量的值显式设置为undefined。一样的规则却对于null不适用。只要保存对象的变量尚未真正保存对象,就应该明确地让该变量保存null值。这样作不只能够体现Null做为空对象指针的惯例,并且也能够更好的区分null和undefined。

3.四、Boolean类型

Boolean类型是ECMAScript使用的最多的一种类型。该类型只有两个字面值:true和false。这两个值与数字值不是一回事,true不等于1,而false也不必定等于0。

var found = true;
var lost = false;

须要注意,true和false是区分大小写的。例如,True和False都是不Boolean值,只是标识符。虽然Boolean类型的字面值只有两个,可是ECMAScript中全部数据类型的值都有与这两个Boolean值等价的值。要将一个值转换为其对应的Boolean值,能够调用转型函数Boolean()。

var message6 = 'hello world';
var message6AsBoolean = Boolean(message6);

上面的例子中,字符串message6被转换成了一个Boolean值,被该值保存在message6AsBoolean变量中。能够对任何数据类型的值调用Boolean函数,并且总会返回一个Boolean值。至于返回的Boolean这个值是true仍是false。

取决于要转换值的数据类型及其实际值。下面是转换规则:

数据类型 转换为true的值 转换为false的值
Boolean true false
String 任何非空字符串 ''(空字符串)
Number 任何非0数字值(包括无穷大) 0 和 NaN
Object 任何对象 null
Undefined 不适用 undefined
var str = 'abc';
var str2 = '';
console.log(Boolean(str));
console.log(Boolean(str2));

var num = 123;
var num2 = 0;
console.log(Boolean(num));
console.log(Boolean(num2));

var obj = {};

var obj2 = null;
console.log(Boolean(obj));
console.log(Boolean(obj2));

console.log(Boolean(undefined));

这些转换规则对理解流程控制语句(如 if 语句)自动执行相应的Boolean转换很是重要:

var message7 = 'hello';
	
if( message7 ){	//true
	console.log('Value is true');	
}
//这个实例,字符串message7会被自动转换成了对应的Boolean值(true)。因为存在这种自动执行的Boolean转换,
//所以确切的知道在流程控制语句中使用的是什么变量相当重要。错误的使用一个对象而不是一个Boolean值,
//就有可能改变应用程序的流程。

3.五、Number类型

这种数据类型使用IEEE754格式来表示整数和浮点数值(浮点数值在某些语言中也被称为双精度数值)。为支持各类数值类型,ECMA-262定义了不一样的数值字面量格式。

//最基本的数值自变量格式是十进制整数,十进制整数能够像下面这样:
var intNum = 25;
//除了十进制之外,整数还能够经过8进制或16进制的字面值来表示。
//其中,8进制字面值的第一位必须是0,而后八进制数字序列(0~7)。
//若是字面值中的数值超出了范围,那么前导0将被忽略,后面的数值将被当作十进制数值解析。

var octalNum1 = 070;	//八进制的 56
var octalNum2 = 079;	//无效的八进制数-解析为79
var octalNum1 = 08;		//无效的八进制数-解析为8

//八进制在严格模式下是无效的,会致使支持的JavaScript引擎抛出错误。
//十六进制字面值的前两位必须是0x,后跟任何十六进制数字(0~9及A~F)。其中,字母A~F能够大写,也能够小写。
var hexNum1 = 0xA;		//十六进制的10
var hexNum2 = 0x1f;		//十六进制的31

//在进行算数计算时,全部以八进制和十六进制表示的数值最终将被转换成十进制数值。

JavaScript能够保存 +0 和 -0。正0和负0被认为相等。

3.六、String类型

3.七、Object类型

4、操做符

4.一、一元操做符

4.二、位操做符

4.三、Null类型

4.四、布尔操做符

4.五、乘操做符

4.六、加操做符

4.七、关系操做符

4.八、相等操做符

4.九、条件操做符

4.十、赋值操做符

4.十一、逗号操做符

5、语句

5.一、if语句

5.二、do-while语句

5.三、while语句

5.四、for语句

5.五、for-in语句

5.六、label语句

5.七、break和continue语句

5.八、with语句

5.九、switch语句

6、函数

6.一、理解参数

6.二、没有重载

7、小结

相关文章
相关标签/搜索