JavaScript高级程序设计-----第三章 基本概念

3.1 语法

3.1.1 区分大小写: ECMAScript中的一切(变量,函数名和操作符)都区分大小写。

3.1.2 标识符: 所谓的标识符,就是指变量,函数,属性的名字,或者函数的参数。格式规则如下:

  • 第一个字符必须是一个字母,下划线(_)或者一个美元符号($); 其他字符可以是字母,下划线,美元符号或数字。
  • 按照惯例,ECMAScript标识符采用驼峰大小格式,如myCar,firstSecond,doSomethingImportant

3.1.3 注释: ECMAScript使用c风格的注释,包括单行注释和块级注释。单行注释以两个斜杠开头,如下所示:

//单行注释

块级注释以一个斜杠和一个星号(/*)开头,以一个星号和一个斜杠(*/)结尾,如下所示:

/*
这是一个多行注释
*/

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

"use strict";  //它是一个编译指示

3.1.5 语句: ECMAScript中的语句以一个分号结尾;

3.2 关键字和保留字

ECMA-262描述了一组具有特定用途的关键字,这些关键字可用于控制语句的开始和结束,或者用于执行特定操作等。按照规定,关键字也是语言保留的,不能用作标识符。以下就是ECMAScript的全部关键字(带*号上标的是第五版新增的关键字):
关键字

ECMA-262还描述了另外一组不能用作标识符的保留字。尽管保留字在这门语言中还没有任何特定的用途,但是他们有可能在将来被用作关键字。以下是ECMA-262第三版定义的全部保留字:
保留字
第五版在非严格模式下运行时的保留字缩减为下列这些:
这里写图片描述
在严格模式下,第五版还对以下保留字做了限制:
这里写图片描述
在实现ECMAScript3的JavaScript引擎中使用关键字做标识符,会导致“Identifier Expected”错误。而使用保留字作标识符可能会也可能不会导致相同的错误,具体取决于特定的引擎。

3.3 变量

ECMAScript的变量是松散类型的,所谓松散类型就是可以用来保存任何类型的数据。定义变量时,要用到var操作符(var是一个关键字),后跟变量名(即一个标识符)。如下所示:

var message;

这行代码定义了一个名为message的变量,该变量可以用来保存任何值(像这样未经过初始化的变量,会保存一个特殊的值----undefined),也可以直接初始化变量。

3.4 数据类型

ECMAScript中有5种简单数据类型(基本数据类型):Undefined,Null,Boolean,Number和String。还有一种复杂的数据类型Object,Object本质上是由一组无序的名值对组成的。

3.4.1 typeof操作符
ECMAScript是松散类型的,typeof用来检测变量的数据类型:
undefined-------如果这个值未定义
boolean-------如果这个值是布尔值
string---------如果这个值是字符串
number--------如果这个值是数值
object--------如果这个值是对象或者null
function--------如果这个值是函数
下面是使用typeof操作符的几个例子:

var message = "some string";
alert(typeof message);//"string"
alert(typeof (message));//"string"
alert(typeof 95);//"number"

注意:typeof是一个操作符不是一个函数,所以例子中的圆括号尽管可以使用,但不是必需的。

3.4.2 Undefined类型
Undefined类型只有一个值,即特殊的undefiend。变量声明之后未初始化,则返回undefiend。如下:

var message;//这个变量声明之后默认取得了undefiend值
//下面这个变量并没有声明
//var age;
alert(message);//“undefined”
alert(age);//产生错误

对未声明的变量执行typeof操作符同样返回undefiend

var message;//这个变量声明之后默认取得了undefiend值
//下面这个变量并没有声明
//var age;
alert(typeof message);//“undefined”
alert(typeof age);//“undefined”

3.4.3 Null类型
Null类型是第二个只有一个值得数据类型,即这个特殊的值是null。从逻辑角度看,null值表示一个空对象指针,而这也正是使用typeof操作符检测null值时会返回“object”的原因,如下面例子所示:

var car = null;
alert(typeof car);//“object”

3.4.4 Boolean类型
Boolean类型是ECMAScript中使用最多的一种类型,该类型只有两个字面量:true和false

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

var num1= 10;//整数
var num2 = 070;//八进制的56   八进制的第一位数必须为0,字序列(0-7),若超出字序列,则前导零被忽略,后面的值当做十进制解析。
var num3 = 0xA; //十六进制的10  十六进制的前两位必须是0x,后跟任何十六进制的数字(0-9及A-F)。其中,字母可以大写也可以小写。

在进行计算时,八进制和十六进制的数值最终都将转换成十进制数值。

(1) 浮点数值

所谓的浮点数值,就是该数值中必须包含一个小数点,并且小数点后面必须至少有一位数字。
对于那些极大或者极小的数值,可以用e表示法(即科学计数法)表示浮点数值。用e表示法表示的数值等于e前
面的数值乘以10的指数次幂。如下:

var floatNum1 = 3.125e7; //等于31250000  它表示的实际含义就是“3.125乘以10^7”
var floatNum2 = 3e-7; //等于0.0000003 

浮点数值的最高精度是17位小数。

(2) 数值范围

由于内存的限制,ECMAScript并不能保存世界上所有的数值。如果这个数值超出范围,是个负数就会被转换成-Infinity(负无穷),正数则会被转换成Infinity(正无穷)。要想确定一个数值是不是有穷的,可以使用isFinite()函数。这个函数在参数位于最小和最大数值之间时会返回true,如下所示:

var result = Number.MAX_VALUE + Number.MAX_VALUE;
 alert(isFinite(result));  //false

(3) NaN

NaN,即非数值是一个特殊的数值。为防止代码块未返回响应的数值而停止运行就会返回NaN,如:在其他编程里,任何数值除以零会报错,代码块停止执行,但是在ECMAScript里任何数值除以0会返回NaN,不会影响代码块的执行。NaN本身有两个非同寻常的特点:

  • 首先,任何涉及NaN的操作(例如:NaN/10)都会返回NaN,这个特点在多步计算中有可能导致问题。
  • 其次,NaN与任何值都不相等,包括NaN本身。
 alert(NaN == NaN);  //false

针对NaN的这两个特点,EMCAScript定义了isNaN函数。这个函数接受一个参数,这个参数可以是任何类型,它会帮我们确定这个参数是否“不是数值”。不是数值返回true。例子如下:

alert(isNaN(NaN));  //true  
alert(isNaN(10));  //false  10是一个数值
alert(isNaN(“10”));  //false   可以被转换成数字10
alert(isNaN(“blue”));  //true  不能转换成数字
alert(isNaN(true));  //false  可以被转换成数值1

(4) 数值转换
有3个函数可以把非数值转换为数值:Number(),parseInt(),parseFloat()。第一个函数,即转型函数Number()可以用于任何数据类型。而另两个函数则专门用于把字符串转换成数值。这3个函数对同样的输入会返回不同的结果。

  • Number()数据类型转换的例子如下:
var num1 = Number("hello world");    //NaN
var num2 = Number("");    //0
var num3 = Number("000011");    //11
var num4 = Number("true");    //1
  • parseInt()数据类型转换的例子如下:
var num1 = parseInt("1234blue");   //1234
var num2 = parseInt("");   //NaN
var num3 = parseInt("0xA");   //10 (十六进制)
var num4 = parseInt("22.5");   //22 
var num5 = parseInt("070");   //56(八进制)  ES5中不支持    应这样写 var num5 = parseInt("070",8);
var num6 = parseInt("70");   //1234(十进制)
var num7 = parseInt("0xf");   //15(十六进制)

3.4.6 String 类型
String类型用于表示由零或多个Unicode字符组成的字符序列,即字符串。字符串可由单引号或双引号表示,注意单双引号的匹配,成对出现。
(1) 字符字面量
String数据类型包含一些特殊的字符字面量,也叫转义序列,用于表示非打印字符,或者具有其他用途的字符。
特殊的字符字面量
(2) 字符串的特点
ES中的字符串是不可以改变的,也就是说字符串一旦创建,值就不能改变。要改变某个变量保存的字符串,首先要摧毁原来的字符串,用另一个包含新值的字符串填充该变量。

(3) 转换为字符串

  • toString方法:数值,布尔值,对象和字符串值都有toString()方法,还可以输出二进制,八进制,十六进制,乃至其他任意有效进制格式表示的字符串值,但是Null和Undefined值没有这个方法。
var age = 11;
var ageAsString = age.toString();  //字符串"11"
var found = true;
var foundAsString = found.toString();  //字符串“true”
var num = 10;
alert(num.toString(2));  //二进制“1010”
alert(num.toString(16));   // 十六进制a
  • 转型函数String():能够将任意类型的值转换为字符串。
var value1 = 10;
var value2 = true;
var value3 = null;
var value4 ;
alert(String(value1));  //   “10”
alert(String(value2));  //   “true”
alert(String(value3));  //   “null”
alert(String(value4));  //   “undefined”

3.4.7 Object类型
ECMAScript中的对象其实就是一组数据和功能的集合。创建Object类型的实例并为其添加属性或方法,就可以创建自定义对象。如下所示:

var o = new Object();     //如果不传参数,可以将括号省略

Object的每一个实例都具有下列属性和方法:

  • Constructor:保存着用于创建当前对象的函数。对于前面的例子而言,构造函数(constructor)就是Object()。
  • hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中(而不是在实例的原型中)是否存在。其中作为参数的属性名(propertyName)必须以字符串的形式指定(例如:o.hasOwnProperty(“name”))。
  • isPrototypeOf(object): 用于检查传入的对象是否是另一个对象的原型。
  • propertyIsEnumerable(propertyName):用于检查给定的属性是否能使用for-in来枚举。与hasOwnProperty一样,作为参数的属性名必须以字符串的形式指定。
  • toLocaleString():返回对象的字符串表示,该字符串与执行环境的地区对应。
  • toString():返回对象的字符串表示。
  • valueOf():返回对象的字符串,数值或布尔值表示。通常与toString()方法的返回值相同。

3.5 操作符

ECMA-262 描述了一组用于操作数据值的操作符,包括算术操作符(如加号,减号),位操作符,关系操作符合相等操作符。
3.5.1 一元操作符
只能操作一个值的操作符叫做一元操作符。
(1) 递增和递减操作符(前置型和后置型)

//前置型
var num1 = 2;
var num2 = 21;
var num3 = --num1 + num2;  // 输出22
var num4 = num1 + num2;  // 输出22
//后置型
var num1 = 2;
var num2 = 21;
var num3 = num1-- + num2;  // 输出23
var num4 = num1 + num2;  // 输出22

(2) 一元加和减操作符(相当于正负号)

3.5.2 位操作符
位操作符用于在最基本的层次上,即按内存中表示数值的位来操作数值。64位的值转换成32位的整数,再将结果换成64位。
(1) 按位非(NOT)
按位非操作符由一个波浪线(~)表示,执行按位非的结果就是返回数值的反码(数值加一取反)。

var num1 = 25;		  //二进制0000000000000000000 000000011001
var num2 = ~num1;   //二进制11111111111111111111111111100110
alert(num2);   // -26

(2) 按位与(AND)
按位与操作符由一个和号字符(&)表示,它有两个操作符数。从本质上讲,按位与就是将两个数值的每一位对齐,根据下表中的规则,对相同位置上的数执行AND操作:
按位与执行AND操作规则
下面看一个对25和3执行按位与的例子:

var result = 25 & 3;
alert(result);     // 1

可见对25和3执行按位与的结果是1,解析如下:
按位与例子解析
(3) 按位或(OR)
按位或操作符由一个竖线符号(|)表示,同样也有两个操作数。按位或操作遵循下面这个真值表。
按位或规则
如果前面的例子执行按位或操作,则代码如下:

var result = 25 | 3;
alert(result);     // 27

按位或例子解析

(4) 按位异或(XOR)
按位异或操作符由一个插入符号(^)表示,也有两个操作数。以下是按位异或的真值表:
按位异或真值表及例子
25与3按位异或的结果是26,解析如下:
按位或例子解析
(5) 左移(<<)
左移操作符由两个小于号(<<)表示,这个操作符会将数值的所有位向左移动指定的位数。例如:
将数值2(二进制码位10)向左移动5位,结果就是64(二进制码位1000000),代码如下:

var oldValue = 2;    //等于二进制的10
var newValue = oldValue << 5;     // 等于二进制的1000000,十进制的64

注意:左移不会影响操作数的符号位。换句话说,如果将-2向左移动5位,结果将是-64,而非64。

(6) 有符号的右移(>>)
有符号的右移操作符有两个大括号(>>)表示,这个操作符会向右移动。但保留符号位(即正负号标记)。有符号的右移操作与左移操作恰好相反,即如果将64向右移动5位,则变回2。

var oldValue = 64;    //等于二进制的1000000
var newValue = oldValue >> 5;     // 等于二进制的10,十进制的2

(7) 无符号右移(>>>)
无符号右移操作符由三个大括号(>>>)表示,这个操作符会将数值的所有32位向右移动。对于正数来说,无符号右移与有符号右移相同。但是对于负数来说就不一样了。

3.5.3 布尔操作符
布尔操作符一共有三个:非(NOT),与( AND)和或( OR )。

  1. 逻辑非(逻辑非操作符由一个叹号(!)表示)
  2. 逻辑与(逻辑与操作符由两个和号(&&)表示),有两个操作数。真值表如下:
    逻辑与真值表
  3. 逻辑或(逻辑或操作符由两个竖线(||)表示),有两个操作数。真值表如下:
    逻辑或真值表

3.5.4 乘性操作符

  1. 乘法(*)
  2. 除法(/)
  3. 求模(%)

3.5.5 加性操作符

  1. 加法(+)
  2. 减法(-)

3.5.6 关系操作符

小于(<),大于(>),小于等于(<=)和大于等于(>=)

3.5.7 相等操作符

  1. 相等(==)和不等于(!=)
  2. 全等(===)和不全等

3.5.8 条件操作符
条件操作符
3.5.9 赋值操作符
简单的赋值操作符由等于号表示(=),作用是把右侧的值赋给左边的变量。
每个主要的算术操作符(以及个别的其他操作符)都有对应的复合赋值操作符。这些操作符如下所示:
复合赋值操作符
3.5.10 逗号操作符
使用逗号操作符可以在一条语句中执行多个操作,如下面的例子:

var num1 =  1, num2 = 2, num3 = 3;

逗号操作符还可以用来赋值,用于赋值时,逗号操作符总会返回表达式中的最后一项:

var num = (5,1,4,5,0);  // num的值为0

3.6 语句

ECMA-262规定了一组语句(也称为流控制语句)。

3.6.1 if语句
if语句语法如下:

if(condition)statement1 else statement2

condition条件为true,则执行语句1(statement1 ),条件为false,执行语句2(statement2)。

3.6.2 do-while 语句
do-while语句是后测试语句,即只有循环体中的代码执行之后,才会测试出口条件。语法如下:

do{
	statement
}while( expression )

3.6.3 while 语句
while语句是前测试语句,就是在循环体内的代码被执行之前,就会对出口条件求值。语法如下:

while(expression){
	statement
}

3.6.4 for 语句
for语句也是前测试语句,但它具有在执行循环之前初始化变量和定义循环后要执行的代码的能力。语法如下:

for( initialization; expression; post-loop-expression ) { statement }

3.6.5 for-in 语句
for-in语句是一个精准的迭代语句,可以用来枚举对象的属性。语法如下:

for(property in expression) statement
var obj = {name:'Json’, age:12, sex:1};
for (var prop in obj) {
  console.log("obj." + prop + " = " + obj[prop]);
}

// Output:
// "obj.name = Json"
// "obj.age = 12"
// "obj.sex = 1"

3.6.6 label 语句
使用label语句在代码中添加标签,以便将来使用。语法如下:

label: statement

下面是一个示例:

start: for(var i=0; i<count; i++){
	alert(i);
}

这个例子中定义的start标签可以在将来由break或continue语句引用。加标签的语句一般都要与for语句等循环语句配合使用。

3.6.7 break 和 continue语句
break 和 continue语句用于在循环中精确地控制代码的运行。其中break语句会立即退出循环,强制继续执行循环后面的语句。而continue虽然也是立即退出循环,但是退出循环后会从循环的顶部继续执行。

3.6.8 with语句
with语句的作用是将代码的作用域设置到一个特定的对象中,语法如下:

with( expression ){ statement }

定义with语句的目的主要是为了简化多次编写同一个对象的工作,例子如下:

var qs = location.search.substring(1);
var hostName = location.hostname;
var url = location.href;

//用with语句写如下
with(location){
var qs = search.substring(1);
var hostName = hostname;
var url = href;
}

3.6.9 switch语句
switch语句和if语句关系最为密切。语法如下:

switch( expression ){
 case value: statement
 	break;
 case value: statement
    break;
 case value: statement
 	break;
 default: statement
}

3.7 函数

函数对于任何语言来说都是一个核心的概念。通过函数可以封装任意多条语句,而且可以在任何地方,任何时候调用执行。ECMAScript中的函数使用function关键字来声明,后跟一组参数以及函数体。函数的基本语法如下所示:

function functionName(arg0,arg1,.....argN){
	statements
}

3.7.1 理解参数
ECMAScript函数不介意传递进来多少个参数,也不在乎传进来的参数是什么数据类型。原因是ECMAScript函数的参数在内部是用一个数组来表示的,不管传进来的参数有几个,函数接收到的始终是一个数组。

3.7.2 没有重载
ECMAScript函数不能像传统意义上实现重载。如何在ECMAScript中定义了两个名字相同的函数,则该名字只属于后定义的函数。例子如下:

function addSomeNumber( num ){
	return num + 100;
}
function addSomeNumber( num ){
	return num + 200;
}
var result =  addSomeNumber( 100);   //300

函数重载扩展:

  1. 什么是重载?
    简单地说,就是函数或者方法有相同的名称,但是参数列表不相同的情形,这样同名不同参数的函数或者方法之间,互相称之为重载函数或者方法。 所以说,重载主要需要两点:第一,同样的函数名。第二,不同的函数参数。
  2. 首先, js没有函数签名的概念(js的参数是由包含0或者多个值的数组来表示的。它所谓的命名参数只是提供便利,但不是必须的。在其他语言中,命名参数这块必须要求事先创建函数签名,而将来的调用也必须与该签名一致。js没有这些条条框框,解析器不会验证命名参数,所以说js没有签名。)真正的重载是不可能做到的。其次,如果js中定义了两个名字相同的函数,则该名字只属于后定义的函数。
  3. ECMAScript函数不介意传进来的参数个数和类型。也就是说,在你定义了函数只接受两个参数之后,你仍然可以在调用的时候传递零或者多个参数。这并不会报错。原因在于arguments对象。ECMAScript中,函数的参数始终是存放在一个数组中,而通过arguments对象,就可以访问带这个数组。所以,只需要length属性既可以确定调用函数时传递了多少个参数。
  4. 通过检查传入函数中参数的数量,js函数就可以做出不同的反应,这可以间接达到重载的目的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值