2013-3-16 | 发布者:www.sealiu.tk
我的笔记:
1.ECMAScript中德一切(变量,函数名和操作符)都区别大小写;
2.标示符必须以字母,下划线或美元符号($)为第一个字符;
3.惯例:ECMAScript标识符采用驼峰大小写格式:
第一个单词小写,剩下每一个单词首字母大写;例子:doSomethingImportant ;
4.在函数中省略var操作符,可以创建一个全局变量。但却不推荐这样做,因为局部作用域中定义全局变量难以维护,而且若有意忽略var操作符,也会由于相应变量不会马上就有定义而导致不必要的混乱;
5.可以使用一条语句定义多个变量,只用中间用逗号隔开即可:
var message="hi",
found=false,
age=29;
6.数据类型:
6.0:-----------------------------------------------------------------------------------
typeof操作符,对于每一个值用typeof可能返回下列某个字符串:"undefined" "boolean" "string" "number" "object" "function";
typeof的操作数可以是变量,也可以是字面量;
alert(typeof null); //“object”
从技术的角度,function应属于一种对象,但有一些特殊的属性才与其他的对象加以区分的对待;所以会单独列出来;
6.1:使用undefined类型---------------------------------------------------------------
使用var声明变量但未对其加以初始化时候,这个变量的值就是:undefined;
例如:var message;
alert(message==undefined); //true;
可以显式地把一个变量的值设置为undefined;引入这个值是为了区别空对象指针与未初始化的变量;
6.2:Null类型--------------------------------------------------------------------------
Null类型也只有一个值就是null;从逻辑的角度来看,null值标识一个空对象指针,而这也正是使用typeof操作符检测null会返回"object"的原因;
若定义的变量准备在将来用于保存对象,那么最好将变量初始化为null而不是其他值;这样一来,一检查null值就可知道变量是否已经保存了一个对象的引用:
example:
if(car!=null){
//对car对象执行某些操作;
}
实际上undefined值是派生自null值的,ECMA-262规定对应他们的相等性测试返回true;
alert(null==undefined); //true;
6.3:Boolean类型----------------------------------------------------------------------
该类型只有两个字面量:true和false;另外Boolean类型的字面值区分大小写的;
各种数据类型及其对应的转换规则:
6.4:Number类型------------------------------------------------------------------------
八进制字面值的第一位必须是0(零);如果字面值中的数值有超过范围的,那么前导的0将被忽略,后面的数当作十进制来解析;
十六进制字面值的前两位必须是0x;后面是(0~9及A~F),其中字母可大写也可小写;
ECMAScript能够标识的最小数:5e-324;
ECMAScript能够标识的最大数:1.796931348623157e+308;
用isFinite()函数来确定一个数是不是又穷的;
example:
var result=Number.MAX_VALUE+Number.MAX_VALUE;
alert(isFinite(result)); //fase;
NaN (not a number)
涉及到NaN的操作都会返回NaN;
NaN与任何值都不相等,包括NaN本身;
isNaN()函数会在收到一个值后,会将某些不是数值的值转化成数值,例如:字符串"10"或Boolean值;而任何不能被转换成数值的会使这个函数放回true;
有3个函数可以把非数值转换成数值:Number();ParseInt();ParseFloat();
其中Number();可以用于任何数据类型,另外两个函数专门用于把字符串转换成数值。
在ECMAScript5 JavaScript引擎中,ParseInt()不具备有解析八进制数的能力;
var num=parseInt("070"); //ECMAScript 5认为是70(十进制)
6.5:Stringr类型------------------------------------------------------------------------
用于表示0个或多个16位Unicode字符组成的字符徐磊,即字符串;
转义序列,用于表示非打印字符:
字符串特点:
var lang="Java";
lang=lang+"Script";
转换为字符串
toString()方法
var num=10;
var found=true;
alert(num.toString()); // "10"
alert(num.toString(2)); // "1010"
alert(num.toString(8)); // "12"
alert(num.toString(16)); // "a"
alert(found.toString()); // "true"字符串;
6.6:Object类型------------------------------------------------------------------------
ECMAScript中的对象就是一组数据和功能的集合;
创建新对象 var o=new Object();
7. 操作符
7.1 一元操作符:++ --
7.2 位操作符:按位非(~),按位与(&),安位或(|),按位异或(^),左移(<<), 有符号位的右移(>>),无符号位的右移(>>>)
7.3 布尔操作符:逻辑非(!),逻辑与(&&),逻辑或(||)
7.4 乘性操作符:乘法,除法,求模(取余%)
操作数为非数值的情况下会执行制动的类型转换;空字符串当做0,布尔值true将被当做1;
对于乘法:有一个数是NaN,则结果就是NaN;
如果是Infinity和0相乘,结果是NaN;
如果有Infinity和非0数相乘,结果是Infinity或则是-Infinity;(符号取决于 有符号的操作数的符号;)
对于除法:Infinity / Infinity 结果是NaN;
0/0 结果是NaN;
非0有限数被0除,结果是Infinity或是-Infinity;
对于求模:
无穷大%有限大 结果是NaN;
有限大%0 结果是NaN;
Infinity%Infinity结果是NaN;
有限大%无穷大 结果是被除数(那个有限大的数);
7.5 加性操作符:加法,减法;
对于加法:Infinity+(-Infinity)=NaN;
对于减法:Infinity-Infinity=NaN;
-Infinity-(-Infinity)=NaN;
Infinity-(-Infinity)=Infinity;
-Infinity-Infinity=--Infinity;
7.6 关系操作符:小于(<),大于(>),小于等于(<=),大于等于(>=),
相等(==),不相等(!=),全等(===),不全等(!==);
这几个操作符都返回一个布尔值;
相等和不相等——先转换再比较;
全等和不全等——仅比较不装换;
7.7 条件操作符:
例如:var max=(num1>num2)? num1 : num2 ;
num1>num2(关系是返回true),则max=num1;否则max=num2;
7.8 赋值操作符:
= , *= , /= , %= , += , -= , <<= , >>= , >>>= ;
7.9 逗号表达式:
var num1=1, num2=2, num3=3;
var num=(1,4,8,4,0); //num的值为0;
8 基本语句:
8.1 if语句
8.2 do-while语句
8.3 while语句
8.4 for语句
8.5 for-in语句
for-in语句是一种精准的迭代语句,可以用来枚举对象属性;
【语法】:for(property in expression) statement ;
【示例】:使用for-in语句循环来显示BOM中window对象的所有属性:
for (var propName in window){
document.write(propName);
}
8.6 label语句
8.7 break和continue语句;
break语句会立刻退出循环,执行循环体后面的语句;
continue语句也会退出循环,但是执行下一次循环;
8.8 with语句;
8.9 switch语句;
9 函数
可以向ECMAScript函数传递任意数量的参数,并可以通过arguments对象访问这些函数;
由于不存在函数签名的特征,ECMAScript函数不能重载;
扩展阅读:
“JavaScript高级程序设计(第3版)学习笔记2——基础语法”
这一篇复习一下ECMAScript规范中的基础语法,英文好的朋友可以直接阅读官方文档。JavaScript本质上也是一种类C语言,熟悉C语言的朋友,可以非常轻松的阅读这篇文章,甚至都可以跳过,不过建议你最好还是看一看,在介绍的同时,我可能会引用一些自认为不易理解且比较流行的用法。
基础语法
1、标识符:所谓标识符,实际上就是指一个满足一定规范,能够被引擎识别的名字,可以用来表示常量、变量、函数名、函数参数、对象、对象属性等所有可命名对象的名称。
(1)区分大小写。
(2)以字母、下划线(_)或美元符号($)开头,其它字符可以为字母、下划线、美元符号或数字。这里的字母包含扩展的ASCII或Unicode字符。
(3)标识符不能是关键字、保留字、true、false、null。(有些浏览器允许使用undefined,有些不能)。
(4)如果对象属性含有空格或其它特殊字符,可以用括号括起来作为一个整体。
2、关键字:在语言本身中有特定用途。
break case catch continue debugger(ES5中新增) default delete do else finally for function if in instanceof new return switch this throw try typeof var void while with
3、保留字:被语言本身保留,将来可能作为关键字。
ES3中的保留字:
abstract boolean byte char class const debugger doubleenum export extends final float goto implements importint interface long native package private protected publicshort static super synchronized throws transient volatile
ES5中的非严格模式下的保留字:
class const enum export extends import super
ES5的严格模式下的保留字:
implements interface let(ES5中新增) package private protected public static yield(ES5中新增)
4、严格模式:在ES5中引入严格模式,通过使用"use strict"来开启严格模式,可以在顶部开启全局严格模式,也可以在函数作用域范围内开启局部严格模式。
"use strict"//开启全局严格模式,在ES3中,不会有任何影响
function fn(){ "use strict"//开启局部严格模式}5、注释:在ECMAScript中,支持两种格式的注释,单行注释和块级注释:
// 单行注释,以两个斜杠//开头
/* * 多行(块级)注释,以一个斜杠/和一个星号*开头,一个星号和一个斜杠结尾,这里中间行的星号*不是必须的 */说 明:随着JS代码越来越复杂,注释也变的越来越重要,而文档自动化也显得愈加重要,目前已经有很多开源JS库用于自动化生成类似于Javadoc的JS文 档,比如JSDoc、YUIDoc等,(2)var操作符:变量使用var来声明,对于未初始化的变量,会默认为undefined,也可以直接使用变量 而不声明(在我看来,这同样是一个没有存在理由的特性),它们之间最重要的区别就是使用var声明时,声明的变量只在当前作用域有效,而不使用var时, 变量就会定义在全局作用域。可以通过下面的例子来体会其中的区别:
var name = 'linjisong'; //定义全局变量并赋值age = 29; //直接使用变量,相当于定义全局变量并赋值//sal; //错误var salary; //定义全局变量,未初始化这个时候,对注释也会有相应的格式要求,有兴趣的朋友可以找相关资料研究。
6、变量:变量在其本质上不过是内存空间在语言级别的外在抽象。
(1)动态类型:在ECMAScript中,变量是动态类型的,你可以在定义的时候初始化为一个Number类型,紧接着,你可以把一个字符串值赋给它:
var age = 29;
age = 'twenty-nine'; //虽然有这种灵活性,但我建议你除非明确知道自己在做什么,否则别这样做。(2)var 操作符:变量使用var来声明,对于未初始化的变量,会默认为undefined,也可以直接使用变量而不声明(在我看来,这同样是一个没有存在理由的特 性),它们之间最重要的区别就是使用var声明时,声明的变量只在当前作用域有效,而不使用var时,变量就会定义在全局作用域。可以通过下面的例子来体 会其中的区别:
var name = 'linjisong'; //定义全局变量并赋值
age = 29; //直接使用变量,相当于定义全局变量并赋值
//sal; //错误
var salary; //定义全局变量,未初始化
//这里只是函数声明,没有实际调用,所以内部定义的变量不会生效
function fn(){
var name = 'oulinhai';//定义局部变量并赋值
age = 23; //给全局变量赋值
work = 'it'; //没有使用var,即便是在函数局部的变量,也会成为全局变量
}
//函数实际调用前
console.info(salary); //undefined
console.info(name); // linjisong
console.info(age); // 29
try{
console.info(work);//由于在全局环境中没有定义work,这里会抛出异常
}catch(e){}
fn();//实际调用,代码中对于变量的变更会显现出来
console.info(name); // linjisong,由于函数内部使用了var,所以不会更改全局的name值
console.info(age); // 23
console.info(work); // it(3)声明提升:这个问题在讲函数声明和函数表达式时还会再次谈到,这里先提一下,看代码:
1 console.info(name);//undefined
2 console.info(getName);//getName()函数
3 console.info(getName());//undefined
4 try{
5 console.info(age);//异常
6 }catch(e){
7 console.info(e);//ReferenceError
8 }
9 console.info(getAge);//undefined
10try{
11 console.info(getAge());//异常
12 }catch(e){
13 console.info(e);//TypeError
14 }
15
16var name = 'linjisong';//变量声明,提升
17 age = 29;//直接使用全局变量,不提升
18function getName(){//函数声明,提升
19return name;
20 }
21var getAge = function(){//变量getAge的声明,提升;获取年龄的匿名函数表达式,不提升
22return age;
23 }
24
25 console.info(name);//linjisong
26 console.info(getName);//getName()函数
27 console.info(getName());//linjisong
28 console.info(age);//29
29 console.info(getAge);//获取年龄的匿名函数
30 console.info(getAge());//29
你有没有自己推断出上面的输出结果?如果已经推断出,可以跳过了,如果还存有疑问,那么先看看下面关于声明提升的描述,然后再回过头来印证上面的输出结果:
A、引擎在解析时,首先会解析函数声明,然后解析变量声明(解析时不会覆盖类型),最后再执行代码;
B、解析函数声明时,会同时解析类型(函数),但不会执行,解析变量声明时,只解析变量,不会初始化。
这里涉及的只是全局作用域,在函数作用域中还有函数参数也和声明提升有关,在后面讲述函数时再讨论。
上 面的代码,首先会把第18行的函数声明和第16、21行的变量声明提升到最开始解析,然后再执行。因此第1、9行因为变量声明提升但尚未初始化,所以输出 undefined,从而第11行因为无法确定是函数类型而抛出类型异常;第2、3行因为函数声明提升并且解析函数类型,所以第2行输出函数,第3行可以 调用函数,但返回值未初始化而输出undefined;第5行因为尚未声明变量,会抛出引用异常。
(4)可以使用一条语句定义多个变量,用逗号分开即可。如:var name='linjisong', age=29, work='it';
(5)在ES5的严格模式下,不能定义名为eval或arguments的变量。
7、语句(1)语句:以一个分号“;”结尾,如果省略分号,由解析器确定语句的结尾。
对于JS中语句可以省略分号的特性,我想不到任何存在的理由,强烈建议每条语句均使用分号来明确结束,不要让解析器花费时间来“猜测”你的程序,而且,更加重要的是,在很多压缩工具中,猜测并不能保证百分百的正确。
(2)代码块:以左花括号({)开始,右花括号(})结束。
在JS中虽然有代码块的概念,但是却没有相应的块级作用域,这是和一般类C语言所不同的。对于控制语句(比如if),不要因为只有一条语句就不使用代码块,这会给维护你程序的伙计种下犯错的种子。
for(var i=0; i<10; i++){}console.info(i);//输出10,在代码块之后仍可以访问i,说明JS无块级作用域if(i < 10)//console.info(i); 不使用代码块,在维护时(比如添加1条语句)容易犯错{ console.info(i);}
花括号({})除了作为代码块来使用外,还有一个很重要的用处就是定义对象字面量,这在后面还会再有论述。
“JavaScript高级程序设计(第3版)学习笔记3——简单数据类型”
数 据类型是编程语言的砖瓦,是所有你能想象到的复杂抽象的基础,在现代编程语言中,除了语言本身内置的一些简单数据类型外,基本上都提供了用于自定义数据类 型的语言机制(在C中也可以利用结构体来实现),这些机制在一定程度上也决定了该语言的流行度和生命力。ECMAScript是一种动态类型的语言,构建 于5种简单数据类型(Undefined、Null、Boolean、Number、String)和一种复杂数据类型(Object)的基础之上。这篇 文章就来复习一下简单数据类型,我会尽量从编程实践的角度来描述,下面代码运行环境为FireFox 14.0.1。
简单数据类型
首 先需要说明的是,在ECMAScript中,上述5种简单数据类型,其中Boolean、Number、String都有同名的内置包装对象,而简单数据 类型的字面值(变量)会根据情况自动包箱,从而可以直接调用方法,至于具体可以调用哪些方法,在讨论内置对象时再详细说明:
console.info(true.toString());//true,相当于使用Boolean()包装之后再调用
console.info(Boolean(false).toString());//false,将false转换为Boolean类型值
console.info(new Boolean(false).toString());//false,将false使用Boolean()包装
console.info(false.toString());//false,相当于使用Boolean()包装之后再调用
console.info('test'.toString());//test,相当于使用String()包装之后再调用
try{
console.info(undefined.toString());//没有相应包装类型,抛出异常
}catch(e){
console.info(e);//TypeError
}
try{
console.info(null.toString());//没有相应包装类型,抛出异常
}catch(e){
console.info(e);//TypeError
}
var num = 4;
console.info(num.toString());//4,可以直接在简单数值变量上调用方法,相当于使用Number()包装之后再调用
//console.info(3.toString());//SyntaxError,语法错误不能使用try捕获,说明不能直接在数值字面量上调用其次说一下实际用的最多的数据转换:
(1)转换为Boolean:!!value
(2)转换为Number:+value
(3)转换为String:''+value
下面再具体说明5种简单数据类型:
1、Undefined类型
Undefined数据类型只有一个取值:undefined。
(1)所有未初始化的值都默认为undefined(也就没有必要把一个变量显示初始化为undefined了)。
(2)在函数作用域中,没有传入实际参数的函数形参为undefined。
(3)函数没有明确返回或者return;的时候,返回值为undefined。
(4)在ECMAScript中,规定null==undefined返回true,而null===undefined返回false。
(5)undefined相应的Boolean值为false。
(6)使用typeof作用于undefiend时,返回字符串'undefined',作用于一个从未声明的“变量”时,也会返回'undefined'。
(7)undefined转换数值为NaN,转换字符串为'undefined'。console.info(undefined===undefined);//true
console.info(typeof undefined);//undefined
console.info(typeof noDefined);//undefined,未定义的标识符,使用typeof也返回undefined,这也是未定义的标识符唯一可用的的操作符
console.info(!undefined);//true,这里返回true,正是很多条件语句中判断变量是否初始化的基础
console.info(!!undefined);//任何一个值,使用双重否定!!都会将其转换为相应的Boolean值,这里说明undefiend相应的Boolean值为false
console.info(undefined==null);//ES中规定,null与undefined相等性测试返回true
console.info(undefined===null);//但undefined与null毕竟是两个数据类型,使用全等比较时,返回false
console.info(typeof undefined==undefined);//false,typeof undefined返回的是一个字符串'undefined',所以这里输出false
console.info(+undefined);//NaN,转换数值时为NaN
console.info(''+undefined);//undefined,转换为字符串'undefined'2、Null类型
Null类型也只有一个值:null。(1)对null值使用typeof时,返回字符串'object'。
(2)null相应的Boolean值为false。
(3)如果一个变量用于保存一个对象,建议初始化为null。
(4)null转换数值为0,转换字符串为'null'。
console.info(null===null); //trueconsole.info(typeofnull);//objectconsole.info(!null); //trueconsole.info(!!null);//false,说明null相应的Boolean值为false
console.info(undefined==null);//true
console.info(undefined===null);//false
console.info(+null);//0,转换为数值0
console.info(''+null);//null,转换为字符串'null'3、Boolean类型
Boolean类型只有两个值:true和false。(1)虽然只有两个值,但是任何一种数据类型的值都能转换为与其相对应的Boolean值,转换方式主要有三种:
A、通过转型函数Boolean()转换
需 要注意的是,当Boolean()作为转换函数时,会转换为一个与其相应的Boolean值,当作为构造函数时,会创建一个对象,而任意非空对象的 Boolean值都是true,有时候这会造成误解,建议就是不使用Boolean()。对于String()、Number()也有类似情况。
B、通过双重否定!!操作符转换
C、通过隐式转换,比如一些条件语句中
(2)Boolean类型的true和false,使用typeof时,均返回字符串'boolean'。
(3)在转换为数值时,true和false分别转换为1和0,转换为字符串时,分别为'true'和'false'。
var value = 'test';
var empty = '';console.info(!!value);//true
console.info(!!empty);//false
console.info(Boolean(value));//true
console.info(Boolean(empty));//false
console.info(!!value === Boolean(value));//true,说明两种转换方式等价
console.info(!!empty === Boolean(empty));//true
console.info(new Boolean(value));//Boolean对象,注意这里使用了new,会创建一个对象
console.info(new Boolean(empty));//Boolean对象
if(value){//隐式转换为true
console.info(value);//test
}
if(empty){//隐式转换为false,不执行括号内部语句
console.info('empty');
}
if(new Boolean(empty)){//先创建对象,再隐式转换为true,会执行括号内部的语句
console.info('empty');//empty
}
console.info(typeoftrue == 'boolean');//true
console.info(+true);//1,一元操作符,转换为数值1
console.info(+false);//0
console.info(''+true);//true,重载后的+操作符,转换为字符串'true'
console.info(''+false);//false具体的转换规则如下:
4、Number类型
在ECMAScript中,没有单独的整型、浮点型,只有一个Number类型,使用IEEE754格式来表示(这种表示法在计算时会有舍入误差),在 这里不去细究底层实现,这些东西在学校学C语言的时候已经很头痛了,不想再头痛一次。下面我把实际编程中用的最多的放到最前面来讲,这一般来说已经足够, 对于不想被太边缘的细节所困扰的朋友,随时可以跳过后面关于Number的论述。
(1)数值转换:主要是下面的三个转换函数
Number()函数:和Boolean()类似,将数据转换成Number类型,和使用一元加操作符(+)作用相同,建议使用 + 操作符,比较简单。
parseInt()函数:解析整数,可以传入数据和进制,如parseInt('070',8)输出10进制的56。
parseFloat()函数:解析浮点数,只能接受一个参数,需要注意的是,如果被解析的数据结果是整数,会直接返回整数。
注:使用Number()和+转换时,true—>1,false—>0,undefined—>NaN,null—>0,空字符串—>0,非空字符串—>按数值解析。
var trueVal = true;
var falseVal = false;
var undef = undefined;
var nullVal = null;
var intVal = '1';
var floatVal = '1.0';
var strVal = 'test';
var empty = '';
console.info(Number(trueVal));//1
console.info(Number(falseVal));//0
console.info(Number(undef));//NaN
console.info(Number(nullVal));//0
console.info(Number(intVal));//1
console.info(Number(floatVal));//1
console.info(Number(strVal));//NaN
console.info(Number(empty));//0
console.info(+trueVal);//1
console.info(+falseVal);//0
console.info(+undef);//NaN
console.info(+nullVal);//0
console.info(+intVal);//1
console.info(+floatVal);//1
console.info(+strVal);//NaN
console.info(+empty);//0
console.info(parseInt(trueVal));//NaNconsole.info(parseInt(falseVal));//NaN
console.info(parseInt(undef));//NaN
console.info(parseInt(nullVal));//NaN
console.info(parseInt(intVal));//1
console.info(parseInt(floatVal));//1
console.info(parseInt(strVal));//NaN
console.info(parseInt(empty));//NaN
console.info(parseFloat(trueVal));//NaNconsole.info(parseFloat(falseVal));//NaN
console.info(parseFloat(undef));//NaN
console.info(parseFloat(nullVal));//NaN
console.info(parseFloat(intVal));//1
console.info(parseFloat(floatVal));//1
console.info(parseFloat(strVal));//NaN
console.info(parseFloat(empty));//NaN说 明:这些转换函数的行为可能会由于浏览器的不同实现而不同,建议在实际编程过程中对存有疑问的先自行编写测试。在《JavaScript高级程序设计(第 3版)》中,这一节描述的也有很多地方和我实际运行的结果不同,比如原书说parseInt()只能解析字符串,但是下面的代码也可以运行:
var object = {
value:1,
toString:function(){
returnthis.value;
}
};
console.info(parseInt(object));//1(2) 整数和浮点数:受C语言熏陶的人,肯定要固执的区分一下整数和浮点数吧!在ECMAScript中,他们没有预想的那么有差别,简单点,含有小数点且小数 点后至少有一位不是0的数值就是浮点数,否则就是整数,比如1.01是浮点数,1.、1.00因为小数点后没有不是0的数,引擎会解析成整数1。你可能会 设想两个整数相除结果也会取整吧,比如3 / 2 = 1,但是在ECMAScript中,不要担心这些,已经还原其数学属性了,你会发现 3 / 2 = 1.5了,这一点,在运算符相关部分还会再提及。
(3)进制:也称进位制,实际上就是进位(低位向高位)的方法,每种进制都有一个基数, 当低位数值达到这个基数时,就向高位进1。在日常生活中,用的最多的自然是10进制,比如10角就进位为1元,在时间度量中,还有24进制(24小时为1 天)、60进制(60秒为1分),在古代,也有使用16进制的(想一想半斤八两吧)。但是在计算机的处理中,由于电流只有通和不通两种状态,所以只能处理 2进制数据,不过这对于自然人来说不好理解,于是又使用8进制、16进制作为10进制和2进制转换的中间状态。
在ES3中,可以使用8进制、10进制、16进制,但是在ES5中,8进制已经被禁用了。
8进制:以1位数字0开始,后面是8进制数字序列(0~7),如果数字超过了7,会忽略前导0而作为10进制处理,比如08会解析为10进制的数字8。
16进制:以1位数字0和1个字母x开始,后面是16进制数字序列(0-9a-fA-F)。
10进制:可以直接将所有数位一一写出来,也可以使用科学计数法(不明白?找一本中学数学教科书来看看吧)来表示。
(3) 特殊值:在ECMAScript中,有2个特殊的数值NaN和Infinity需要注意一下,前者表示不是一个数值(Not a Number),后者表示不在表示范围内的数值,还可以使用正负号表示方向。对于这两个特殊值,这里不去考察具体的运算规则(你若感兴趣,可以自行测试, 我在下面也会举一些例子),只做如下两点说明:
A、不能用val==NaN来判断一个变量是否为NaN,而要使用全局的isNaN()函数,该函数接受一个参数,当参数可以转换为数值时返回true,否则返回false。
B、尽量不要使用val==Infinity判断是否超出范围,而使用全局的isFinite()函数,该函数接受一个参数,当参数数值处于表示范围内 时返回true,否则返回false。这里所说的表示范围是指从Number.MIN_VALUE到Number.MAX_VALUE,另外,在 Number里面,还有属性Number.NEGATIVE_INFINITY和Number.POSITIVE_INFINITY,其值分别为 Infinity和 -Infinity。
console.info(0/0); //NaN
console.info(NaN==NaN);//false
console.info(NaN+1);//NaN
console.info(NaN/NaN);//NaN
var notNumber = NaN;
console.info(notNumber==NaN);//false
console.info(isNaN(notNumber));//true
console.info(1/0); //Infinity
console.info(-1/0); //-Infinity
console.info(1/Infinity);//0
console.info(Infinity/Infinity);//NaN
console.info(Infinity==Infinity); //true
var inf = Infinity;
console.info(inf==Infinity);//true
console.info(!isFinite(inf));//true
console.info(!isFinite(NaN));//true
console.info(isNaN(Infinity));//false注:在《JavaScript高级程序设计(第3版)》中第29页说任何数值除以0都会返回NaN,实际上并非如此。
5、String类型
和一般类C语言不同,在ECMAScript中,没有字符类型,而将字符串类型String作为一种简单类型,其字面量使用引号(单引号'或双引号“)括起来。
(1)对于字符串类型的操作,加号“+”被重载,任意一个数值与字符串相加,都会先将其使用String()转换成字符串,然后将两个字符串合并。
(2) 使用String()转换,undefined—>'undefined',null—>'null',true— >'true',false—>'false',数值类型Number—>按数值可见的字符转换,对象Object—>调用 toString。
console.info(''+1+1);//11,而不是2
console.info(''+true);//true
console.info(''+undefined);//undefined
console.info(''+null);//null(3)字符串使用反斜杠“\”来转义,常见的一些转义字符有:
好了,关于简单数据类型,就整理到此。
如果说数据类型是编程语言的砖瓦,那么运算符和操作符则是编程语言的石灰和水泥了,它是将各种数据类型的值有机组合的糅合剂,使得数据值不再只是一 个孤立的值,而有了一种动态的灵性。在ECMAScript中,有非常丰富的运算符和操作符,在这篇文章中将按通常的分类来稍微整理一下,不过在整理之 前,先说明一下:
1、虽然标题是运算符和操作符,然而在我看来并没有多少严格区分的必要,在英文中,貌似也是用一个Operator来表示,所以在下文中我可能会混用。甚至,一些不属于运算符和操作符范畴的,我也整理在这里,只要我觉得必要。
2、对于运算符的优先级,你无需一一牢记——我相信你知道最简单的”先乘除,后加减”,至于其它的,如果你不确定,加上括号好了。在ECMAScript中,优先级相同的从左向右运算。
3、对于一些编程语言通用的运算符,比如常用算术运算符(+-*/),我只会简单的列举一下,不会展开,但是请注意,并不是说这些不重要,相反,这些通用运算符甚至处于一个非常基础的地位,只是我觉得你应该早已经熟悉,没必要在这里花时间强调。
4、那么,这里重点关注什么呢?就是一些在ECMAScript中比较特殊的操作符,或者我认为值得花时间强调的一些地方。
运算符与操作符
【点击看大图】
说明几点:
1、这里的分类并不十分严格,比如按位非(~)、逻辑非(!)、delete、void、typeof,都可以算是一元操作符,而自增(++)在很多资料中也被归为算术操作符之中。我在整理时则主要参考原书分类,也兼顾自然性。
2、加号(+)的用法比较灵活,需注意,特别是用于计算时,忽略了其中的字符串,会很容易犯错误。
3、typeof一般用来判断简单数据类型,如果是对象类型,因为大部分返回的都是object,没有多大实际用处,而instanceof的判断也需要满足同一个上下文的条件,否则也会出错,对于对象类别的判断会在后面讲述对象时再详细说明另外一种更为稳妥的方法。
4、先看下面的代码:
var numVal = 10.00, strVal = '10', strObj = new String('10'); console.info(numVal == strVal);//true console.info(typeof (strVal+strObj));//string
第一个输出的竟然是true,是不是出乎你 的意料?在这里,由于==比较符发生了隐式类型转换,会将Number类型转换为String类型,然后Number类型的10.00因为小数点后没有不 是0的数值,会被解析成整数10,从而比较的时候会相等。第二个输出是string,这其实还是比较容易理解的,strVal是字符串,strObj是字 符串对象,两者相加,会把对象转换成字符串,所以最终结果也是字符串类型。
5、关于符号,重复一下几个流行的用法(这里不涉及正则表达式中的用法):
(1)使用一元加号(+)转换为Number类型。
(2)使用双重逻辑非(!!)转换为Boolean类型。
(3)使用逻辑与(&&)来检测对象是否存在并进行后续操作。
(4)使用逻辑或(||)来给函数参数提供默认值。
(5)使用分组(())来明确指定为表达式。
(6)使用花括号({})来定义对象字面量,JSON数据格式,代码块。
(7)使用中括号([])来定义数组字面量,JSON数据格式,访问数组,访问名称是变量或特殊字符的属性。
6、关于按位运算,虽然结果不是很直观,但是运行效率高,也有很多有趣的应用,比如不使用中间变量直接交换两个数值、判断奇数和偶数、MD5加密等等,有兴趣的朋友可以找相关资料自行研究。
来源:博客园
参考书籍:
[1]Professional JavaScript for Web Developers 3rd Edition:JavaScript高级程序设计(第3版)[美]Nicholas C.Zakes 著 李松峰 曹力译 人民邮电出版社。