文档章节

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

AAASSSSddd
 AAASSSSddd
发布于 2016/11/30 19:52
字数 3763
阅读 26
收藏 0

一、本章简介

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

二、语法

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

2.1、区分大小写

ECMA中的一切(变量、函数名和操作符)都区分大小写。所以test和Test是两个不同的变量。

2.2、标识符

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

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

2.3、注释

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

2.4、严格模式

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

"use scrict";

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

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

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

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

2.5、语句

ECMAScript中的语句以一个分号结尾,虽然语句结尾分号不是必须的,建议任何时候都不要省略它。这样可以避免很多错误。

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

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

var diff = 5 - 3;

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

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

2.6、关键字和保留字

//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.7、变量

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;

三、数据类型

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

3.1、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.2、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.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.4、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.5、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.6、String类型

3.7、Object类型

四、操作符

4.1、一元操作符

4.2、位操作符

4.3、Null类型

4.4、布尔操作符

4.5、乘操作符

4.6、加操作符

4.7、关系操作符

4.8、相等操作符

4.9、条件操作符

4.10、赋值操作符

4.11、逗号操作符

五、语句

5.1、if语句

5.2、do-while语句

5.3、while语句

5.4、for语句

5.5、for-in语句

5.6、label语句

5.7、break和continue语句

5.8、with语句

5.9、switch语句

六、函数

6.1、理解参数

6.2、没有重载

七、小结

© 著作权归作者所有

共有 人打赏支持
AAASSSSddd
粉丝 17
博文 51
码字总数 48587
作品 0
杭州
程序员
开源书籍-JavaScript 编程精解

《JavaScript 编程精解》(Eloquent JavaScript)第三版,是由马尔奇·哈弗贝克(Marlin Haverbeke)JavaScript程序员编写的JS入门书籍,Marlin Haverbeke通晓多种编程语言,在Web开发方面积累...

marsdream
06/04
0
0
javascript 完美继承机制

有关javascript的继承在《javascript 高级程序设计》第三版 中讲的很详细,也极力推荐初学者学习本书。 function object(o){function F(){}F.prototype = o;return new F();} function inher...

造化玉碟
2014/04/28
0
0
如果想成为一名顶尖的前端,这份书单你一定要收藏!

欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由腾讯IVWEB团队 发表于云+社区专栏 作者:link 2014年一月以来,自己接触web前端开发已经两年多了,记录一下自己前端学习路...

腾讯云加社区
09/17
0
0
JavaScript函数内部属性arguments

JavaScript高级程序设计(第三版),个人的读书笔记. 在JS函数内部,有两个特殊的对象:arguments和this,我们先讲下arguments。 arguments是一类数组对象,包含着输入函数中的所有参数。除此之外...

夏诺风
2014/04/19
0
0
JavaScript 编程精解 中文第三版 零、前言

零、前言 原文:Introduction 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译 部分参考了《JavaScript 编程精解(第 2 版)》 We think we are creating the system for our own purp...

ApacheCN_飞龙
06/01
0
0

没有更多内容

加载失败,请刷新页面

加载更多

c++_CWinApp

CWinApp:MFC 中的主应用程序类封装用于 Windows 操作系统的应用程序的初始化、运行和终止. ON_COMMAND(ID_FILE_NEW, &CWinApp::OnFileNew)ON_COMMAND(ID_FILE_OPEN, &CWinApp::OnFileOpen...

一个小妞
7分钟前
0
0
可变对象传入set

set=([1,2,3]), 其中([ ])只是set的表现形式,并不是把list放入set中 >>> s1=set([1,2,3])>>> L[1, 2, 3]>>> s1{1, 2, 3}>>> s1(L)Traceback (most recent call last): File "<std......

fadsaa
10分钟前
0
0
多生产与多消费:操作栈

代码同“多生产与一消费”,区别在于测试类代码 public class Test { public static void main(String[] args) { MyStack myStack = new MyStack(); Produce produce......

起个昵称好难啊
10分钟前
0
0
@Component 的作用

1、@controller 控制器(注入服务) 用于标注控制层,相当于struts中的action层 2、@service 服务(注入dao) 用于标注服务层,主要用来进行业务的逻辑处理 3、@repository(实现dao访问) ...

踏破铁鞋无觅处
11分钟前
0
0
工厂模式

工厂方法模式 一个抽象产品类,可以派生出多个具体产品类。 一个抽象工厂类,可以派生出多个具体工厂类。 每个具体工厂类只能创建一个具体产品类的实例。 简单工厂模式 又称静态工厂方法模式...

noob_fly
14分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部