一、严格模式
ES5引入了严格模式的概念,严格模式是为javascript定义了一种不同的解析模式与执行模式,在严格模式下,ES3中的不确定行为将得到处理,而且对于某些不安全的操作也会抛出错误,要在整个脚本中启用严格模式,可以在顶部添加如下代码。
"use strict"
这是一条便一直是,也可以在函数内部上方包含这条编译模式,指定函数在严格模式下执行。
function doSomething(){
"use strict"
}
二、变量
有一点必须注意,即用var操作符定义的变量将成为定义该变量作用域中的局部变量。比如:
function test(){
var message = "hi"
}
test();
alert(message); //错误
注意,变量message是在函数中使用var定义的,当函数被调用时,就会创建该变量并为其赋值,而在此之后,这个变量又将被立即销毁,不过可以省略var创建一个全局变量。
在严格模式下给未经声明的变量赋值会导致ReferenceError错误。
三、数据类型
1、ES5有5种基本数据类型:Unidfined、Null、Boolean、Number和String,还有一个复杂数据类型Object,Object本质上是由一组无序的名值对组成的。ECMAScript不支持任何创建自定义类型的机制,而所有值最终都将是上述的6中数据类型之一。
2、typeof 操作符
由于ECMAScript是松散类型的,因此需要有一种手段来检测给定变量的数据类型,即typeof。对一个值使用typeof会有以下结果
(1)“undefined” 如果这个值未定义
(2)"boolean" 如果这个值是boolean值
(3)"string" 如果这个值是字符串
(4)“number” 如果这个值是数值
(5)"object" 如果这个值是对象或者null
(6)"function" 如果这个值是方法
注意:typeof是一个操作符而不是函数
3、undefined类型
Undefined类型只有一个值,即特殊的undefined。在使用var声明变量但未对其进行初始化时,这个变量的值就是undefined。
但是对于未声明的变量执行typeof操作符也会返回undefined。
4、Null类型
Null类型是第二个只有一个值的特殊对象,从逻辑角度来看,null值表示一个空指针对象,因此对null类型使用typeof操作符会返回object。如果定义的变量在将来用于保存对象,那么最好将该变量初始化为null而不是其他值,这样只要直接检查null就可以知道相应变量是否已经保存一个对象的引用。
实际上undefined值是派生自null的,因此null == undefined
5、Boolean类型
虽然boolean类型的字面值只有两个,但所有类型的值都有与这两个Boolean值等价的值,要将一个值转换为对应的Boolean值,可以调用转型函数Boolean()。
如下所示:
var message = Boolean(message)
数据类型 | 转换为true的值 | 转换为false的值 |
Boolean | true | false |
String | 任何非空字符串 | 空字符串 |
Number | 任何非0数字值,包括无穷大 | 0和NaN |
Object | 任何对象 | null |
Undefined | 不适用 | undefined |
6、Number类型
(1)除了十进制外,还可以通过八进制或十六进制来表示,其中,八进制字面值第一位必须是0,然后是八进制数字,如果字面值的数值超出了范围,那么前导0会被忽略,后面的值当做十进制位解析。
八进制字面量在严格模式下是无效的。
十六进制的前两位必须是0x,后面跟任何16进制数字,可大写也可小写。
(2)浮点数值
所谓浮点数值,就是表示该数值必须包含一个小数点,由于保存浮点数值需要的内存空间是保存整数值的两倍,因此ECMAScript会时不时地将浮点数值转换为整数值。如果浮点值本身表示的是一个整数,那么该值就会转换成一个指数。
对于那些极大或者极小的值,可以用e表示法的浮点数值来表示。用e表示法的表示的数值等于e前面的数值乘以10的指数次幂。
例如var floatNum = 3.125e7。
浮点数值的最高精度是17位小数,但是在算数计算是精度远远不如整数,例如0.1+0.2不等于0.3
(3)数值范围
最小数值:Number.MIN_VALUE 为5e-324
最大数值:Number.MAX_VALUE
如果某某次计算的结果得到一个超出javascript的值,那么这个值将被自动转换为特殊的Infinity值(正无穷),也存在负无穷-Infinity。
如果某次计算返回了Infinity值,那么该值无法参与下次运算。要确定一个数是不是无穷,可以使用isFinite()函数。
Number.NEGATIVE_INFINITY和Number.POSITIVE_INFINITY保存着正无穷和负无穷的值。
(4)NaN
即非数值(No a Number),这个数值用于表示一个本来要返回数值的操作数未返回数值的情况(这样就不会抛出错误了)。
Nan有两个特点,任何涉及NaN的操作都会返回NaN,这个特点在多步计算中可能导致错误,其次,NaN和任何值都不相等,包括其本身。
针对这个特点,定义了isNaN()方法来接收一个参数,来判断该数值是否不是数值。在接收这个值之后,会判断这个值能否转成数值,例如字符串"10"和boolean可以转换成数值。
并且isNaN()也适用于对象,在对象调用isNaN()函数时,会首先调用对象的valueof()方法,然后确定该方法的值是否可以转成数值,如果不能,则基于这个值再调用toString(),再测试返回值。
(5)数值转换
有三个函数可以把非数值转换为数值:Number(),parseInt()和parseFloat(),第一个函数,即转型函数Number()可以适用于任何数据类型,而另外两个函数则专门把字符串转换成数值,这三个函数对于同样的输入会返回不同的结果。
Number转换结果如下:
如果是Boolean值,true和false将分别被转换成1和0。
如果是数字值,只是简单的传入和返回。
如果是null值,则返回0。
如果是undefined,则返回NaN。
如果是字符串,则遵循下列规则:
如果字符串中包含数字,则将其转换为十进制数值,即”123”变成123,“011”变成11(前导0被忽略)。
如果字符串中包含有效的浮点格式,如“1.1”,则将其转换为对应的浮点数值(同样忽略前导0)。
如果字符串中包含有效的十六进制格式,则转换为相同大小的十进制整数。
如果字符串是空的,则将其转换为0
如果字符串包含上述格式之外的字符,则转换为NaN。
由于Number()函数在转换字符串时比较复杂而且不够合理,因此在处理整数时更常用的是parseInt()函数。parseInt()函数在转换字符串时,更多的是看其是否符合数值模式,它会忽略字符串签名的空格,直至找到第一个非空格字符。如果第一个字符不是数字字符或者符号,parseInt就会返回NaN,也就是说parseInt()遇到空字符串会返回0,如果第一个字符是数字字符,parseInt()会继续解析第二个字符安,直到解析完所有字符或者遇到一个非数字数字。例如:“1234blue”会被转换成1234,因为blue会被完全忽略,类似的“22.5”会被转换为22,因为小数点不是有效的数字字符。
如果字符串中的第一个字符是数字字符,parseInt()也能够识别出各种整数格式(十进制、八进制、 十六进制)
也可以给parseInt()传入第一个参数,即指定多少进制,并且如果指定16为第二个参数,可以省略前面的0x
var num1 = parseInt("AF",16) //175
var num2 = parseInt("AF") //NaN
parseFloat()和parseInt()类似,,也是从第一个字符开始解析每个字符,而且也是解析到字符串末尾,或者是遇见一个无效的浮点数字字符为止,也就是说,字符串中的第一个小数点是有效的,而第二个是无效的。
除了第一个小数点有效之外,parseInt()和parseFloat()第二个差别在于他始终都会忽略前导0,parseFloat()可以识别所有浮点数格式,也包括十进制整数格式,但是十六进制格式的字符串则会始终返回0,由于parseFloat()只解析十进制值,,因此他没有用第二个参数指定基数的用法,如果字符串包含的是一个可解析为整数的数,parseFloat()会返回一个整数值。
7、string类型
(1)字符字面变量
即转义字符。
字面量 | 含义 |
\n | 换行 |
\t | 制表 |
\b | 退格 |
\r | 回车 |
\f | 换页 |
\\ | 斜杠 |
\` | 单引号 |
\'' | 双引号 |
\xnn | 以十六进制代码nn表示的一个字符,例如\x41表示"A" |
\xnnn | 以十六进制代码nnn表示一个Unicode字符。 |
var text = "This is the letter sigma: \u03a3."
alert text.length //输出28
其中6个字符长的转义字符表示1个字符
这个属性返回的字符数包括16位字符的数目,如果字符串中包含双节字符,那么length属性可能不会精确的返回字位数目。
(2)字符串的特点
ECMAScript中的字符串时不可变的,也就是说,字符串一旦创建,他们的值就不能翻遍,要改变变量保存的字符串,首先要销毁原来的字符串,然后再用另一个包含新值的字符串填充该变量。
var lang = "Java"
lang = lang + "Script"
(3)转换为字符串
要把一个值转换成一个字符串有两种方式,第一种是使用toString()方法,这个方法唯一要做的就是返回响应值的字符串表现。
var age = 11;
age.toString() //字符串"11"
var found = true;
found.toString() //字符串"true"
数值、boolean值、对象和字符串值(返回字符串的一个副本)都有toString()方法,但null和undefined没有这个方法。
多数情况下,调用toString都不用传递传输,但在调用数值的toString()方法时,可以传递一个参数,即输出数值的基数,二进制、八进制等等。
在不知道要转换的值是不是null或者undefined时,还可以使用String()转型函数,这个函数能够将任何类型的数值转换为字符串,String()函数遵循下列规则:
如果值有toStirng(0方法,则调用没有参数的toString()并返回结果
如果是null或者undefined的话,则返回"null"和"undefined"
8、object类型
ECMAScript中的对象其实就是一组数据和功能的集合,对象可以通过执行new操作符后跟要创建的对象类型的名称来创建,而创建object类型的实例并为其添加属性和方法,就可以创建自定义对象。
var o =new Object()
这个语法与Java中创建对象的语法相似,但在ECMAScript中,如果不给构造函数传递参数,则可以省略后面的括号,也就是说,在像前面这个实例一样不传递参数的情况下,完全可以省略那对括号(但不推荐)
仅仅创建Object对象并没有什么用处,但关键是要理解一个思想,即在ECMAScript中,Object类型是所有他的实例的基础,换句话说,Object类型所具有的任何属性和方法也通常存在于更具体的对象中,Object的每个实例都具有下列属性和方法:
constructor():保存着用户创建当前对象的函数,对于前面的例子而言,构造函数就是Object()。
hasOwnProperty():用于检查给定的属性在当前对象实例中(而不是在实例的原型中)是否存在,其中,作为参数的属性名必须以字符串形式指定。
isPrototypeOf(object):用于检查当前对象是否是传入对象的原型
propertyIsEnumerable(propertyName):用于检查给定的属性是否能够使用for-in语句来枚举,且传入的参数必须以字符串形式对应。
toLocaleString():返回对象的字符串表示,该字符串与执行环境的地区对象。
toString()
valueOf():返回对象的字符串、数字或boolean值表示,通常与toString()的返回值相同。
四、操作符
1、一元操作符
(1)递增递减
递增递减对任何值都适用,也就是说他们不仅仅适用于整数,还可以用于字符串、布尔值、浮点数值和对象,在应用于不同的值时,遵循下列规则:
在应用于一个包含有效数字字符的字符串时,先将其转换为数字,在执行递增递减操作。
在应用于一个不包含有效数字字符的字符串时,先将变量的值设为NaN,字符串变量变成数值变量。
在应用于true/false时,先将其转换为1/0再执行递增递减操作
在应用于对象时,先调用valueOf()方法以取得一个可供操作的值,然后再对该值应用上述规则。
(2)一元加和减操作符
(3)位操作符
在对特殊的NaN和Infinity应用位操作的话,这两个值都会被当成0处理。如果对一个非数值应用位操作符,会先使用Number()函数先将该值转换为一个数值,然后再应用位操作。
(4)逻辑非
如果操作数是一个对象,返回false
如果操作数是一个空字符串/非空字符串,返回true/false
如果操作数数值是0,返回true
如果操作数是非0的任意数,包括Infinity,返回false
如果操作数是null,返回true
如果操作数是NaN,返回true
如果操作数是unidentified,返回true
逻辑非操作符也可以用于将一个值转换为与其对一个的boolean值。而同时使用两个逻辑非操作符,实际上就会模拟Boolean()转型函数,其中,第一个逻辑非操作会基于物流什么操作数返回一个boolean值,而第二个值则对该boolean取反。
(5)逻辑与
逻辑与操作可以应用于任何类型的操作数,而不仅仅是boolean值,在有一个操作数不是boolean值的情况下,逻辑与操作就不一定返回boolean值。
如果第一个操作数是对象,则返回第二个操作数。
如果第二个操作数是对象,则只有在第一个操作数的求值为true,才会返回该对象
如果两个操作数都是对象,则返回第二个操作数。
如果有一个操作数为null,则返回null
如果有一个操作数是NaN,则返回NaN
如果有一个操作数是unidefined,则返回undefined
逻辑与操作属于短路操作,即如果第一个操作数能够决定结果,那么久不会对第二个操作数求值.
(6)逻辑或
与逻辑与相似,如果有一个操作数不是布尔值,逻辑或不一定会返回boolean值
如果第一个操作数是对象,则返回第一个操作数
如果第一个操作数求值为false,则返回第二个操作数
如果第一个操作数的求值结果为false,则返回第二个操作数
如果两个操作数都是对象,则返回第一个操作数
如果两个操作数都是null/NaN/undefined,则返回null
并且其也是短路操作符。
我们可以利用逻辑或的特性来给避免给变量赋值为null或者undefined值。
var myObject = preferredObject || backupObject
(7)乘性操作符
在操作数为非数值的情况下会执行自动类型转换(使用Number()转型函数)。
规则如下:
两个正数或者两个负数相乘的结果都是正数,但是如果只有一个操作数有符号的话则返回负数。
有一个值为NaN则结果为NaN
如果Infinity0相乘,结果是NaN。
如果Infinity与非0数相乘,结果为Infinity或者-Infinity。
如果Inifnity与自己相乘,结果为Infinity。
(8)除法
如果是Infinity被Infinity除,结果是NaN
如果是0被0除,则结果是NaN
如果是非0的有限数被0除,结果是Infinity或者-Infinity
如果是Infinity被任何非0数值除,则结果是Infinity或者-Infinity
(9)求模
如果被除数是无穷大值二除数是有限大的值,则结果是NaN
如果被除数是有限大的值而除数是0,则结果是NaN
如果被除数是有限大的值而除数是无穷大的数值,则结果是被除数
(10)加法操作符
(11)减法操作符
(12)关系操作符
>,<,>=,<=。
如果两个操作数都是数值,则执行数值比较
如果两个操作数都是字符串,则比较两个字符串对应的字符编码值()
如果其中一个操作数是数值,则将另一个操作数转换为数值再进行比较
NaN和任何数比较都返回false
如果一个操作数是对象,则调用这个对象的valueof()方法,如果没有valueof方法,则使用toString。
(13)相等操作符
ECMAScript提供了两组操作符:相等和不相等--先转换再比较,全等和不全等--仅比较而不转换
相等和不相等
相等操作符由==和!=表示,这两个操作符都会先转换操作数然后再比较他们的相等性,并遵循下列规则:
null和unidfined是相等的。
如果操作数是对象,则判断这两个操作数是否都指向都一个对象,是则返回true。
全等和不全等
===和!==
null和undefined使用===会返回false,因为是不同类型的值。
(14)条件操作符
三位运算符
(15)赋值操作符
五、语句
1、for-in
for-in是一种精准的迭代语句,可以用来枚举对象的属性,以下是for-in语句的语法
for(property in expression) statement
for(var propName in Window){
document.write(propName)
}
在这个例子中,我们使用for-in循环来显示BOM中window对象的所有属性,每次执行循环时,都会将window对象中存在的一个属性名赋值给变量propName,这个过程会一直持续到对象中的所有属性都被枚举一次。
但是由于ECMAScript对象的属性没有顺序,因此,通过for-in循环输出的属性名顺序是不可预测的,具体来讲,所有属性名都会被返回一次,但是返回的先后次序可能会有所差异。
之前,如果要迭代的对象的值为null或者是undefined,for-in会抛出错误,ECMAScript5更正了这一个情况,对这种情况不再抛出凑无,而只是不执行循环体,为了保证最大的兼容性,建议在for-in循环中先进行检测。
2、break和continue
break会立即退出循环并且强制执行循环后面的语句,而continue语句虽然也是立即退出循环,但退出循环后会从循环的顶部继续执行。
3、with语句
with语句的作用是将代码的作用域设置到一个特定的对象中。with语句的语法如下:
with(expression) statement
var qs =location.search.substring(1);
var hostName = location.hostname;
with(location){
var qs = search.substring(1);1
var hostName = location.hostname
}
严格模式下不允许使用with语句,并且大量使用with语句将会导致性能下降,因此不建议使用。
4、switch
switch使用的是全等操作符,因此不会发生类型转换。
六、函数
ECMAScript中函数使用function关键字来声明,后跟一组参数以及函数体:
function functionName(arg0, arg1,...argN)
ECMAScript中的函数在定义时不必指定是否返回值,实际上,任何函数在任何时候都可以通过return语句来返回值。
另外,return语句也可以不带任何返回值,在这种情况下,会返回undefined。
七、理解参数
ECMAScript的参数有所不同,ECMAScript函数不介意传递进来多少个参数,也不在意参数类型,因为ECMAScript的参数在内部使用一个数组来表示的。其参数aruments与数组类似,因为可以使用方括号语法访问他的每一个元素,(即第一个是arguments[0],第二个是arguments[1]),因此函数也可以不显式的使用参数,例如
function sayHi(){
alert(arguments[0] + arguments[1]);
}
arguments的值与其对应的参数的值保持同步。但并不是说读取这两个值会访问相同的内存空间,并且arguments的长度是由传入的参数决定的。
没有传递值的命名参数会被自动设置为undefined值,这跟定义了变量却没初始化一样。
严格模式对如果使用arguments做出一些限制,首先,给arguments中的值赋值会变得无效,其次,重写arguments中的值会报错。