基本概念
标识符
所谓的标识符就是变量、函数、属性或者函数的名字,需要遵守以下规则:
- 第一个字符必须是字母,下划线(_),或者美元符号($)
- 其他字符可以是字母,下划线,美元符号或者数字
JavaScript中的一切都对大小写敏感,按照惯例,一般采用驼峰大小写的格式,也就是第一个字母小写,剩下的每个单词的首字母大写:
firstSecond
, myCar
, doSomeThing
注释
单行注释
//单行注释
多行注释
/*
* 这是一个多行注释
* 也叫块级注释
* <-当然,这些星号不是必须的,这里只是为了提高可读性
*/
严格模式
ECMAScript5引入了严格模式(strict mode), 在严格模式下,ECMAScript3中的一些不确定的行为将得到处理,而且对某些对象不安全的操作也会抛出错误。要在整个脚本中启动严格模式只需要在顶部添加如下代码:
"use strict";
这个就是一个字符串,告诉编译器切换到严格模式,当然也可以在单个的函数中定义严格模式:
function doSomeThing(){ |
语句
ECMAScript中语句以分号结尾,但是可以省略,由解析器来确定语句的结尾。推荐任何时候都不要省略分号, 一是可以让意图更加明显,避免很多错误;二是可以放心的删除多余的空格来压缩代码;三是可以提高性能,不用编译器花时间去推测断句。
变量
ECMAScript中的变量采用松散类型,就是变量可以用来保存任何类型的数据。定义变量用关键词var
,后面接上变量名:
var message; |
定义了一个名叫message
的变量,它可以用来保存任何类型的值(但这里未经过初始化的变量将会保存着一个特殊的值——undefined
)。当然也可以在定义变量的同时设定变量的值:
var message = "hello world"; |
所谓的变量就是可以改变的量,所以你可以去改变变量保存的值,甚至,你可以修改变量的类型:
message = 123; //有效,但是不推荐这样做 |
其实不用关键词var
也可以定义变量,直接省略var
即可,区别在于用var
定义的变量是该变量作用域中的局部变量,而省略掉之后成为了全局变量:
function test1(){ |
数据类型
EXMAScript中有5种简单数据类型:Undeifined, Null, Boolean, Number和String;
还有一种复杂数据类型——Object,Object本质上是由一组无序的键值对组成的。
typeof
操作符
由于变量是松散的,所以需要一定的手段来检测给定变量的数据类型,这就是typeof
负责的。对一个值使用typeof
,返回的结果是可能是下列的某一个字符串:
"undefined"
:这个值未定义;boolean
:这个值是布尔值;string
:这个值是字符串;number
:这个值是数值;object
:这个值是对象或者nullfunction
:这个值是函数
typeof
是一个操作符而不是一个函数,所以可以使用圆括号,也可以不使用:
typeof("hello world"); //"string" typeof 98; //"number" |
这里比较令人迷惑的是,null虽然是Null类型的一个值,但是typeof null
返回的却是“Object”而不是“Null”,因为特殊值null被认为是对空对象的引用。
Undefined
类型
Undefined类型只有一个值,就是undefined,在使用var定义变量但未对其进行初始化的时候,这个变量的值就是undeifined。
未定义的变量&&未初始化的变量
|
对于未定义的变量只能执行一项操作,就是使用typeof
检测类型,其他的操作会产生错误。然后typeof
变量不能区分开这两种变量,因为虽然这两种变量从技术角度上讲有本质的区别,但是无论哪种变量,都是不可能执行真正操作的,都归类为"undefined"
。
Null
类型
Null
类型也只有一个值,这个就是null
。从逻辑角度上讲,null
值表示一个空对象的指针,这也是typeof
返回"Object"
的原因。
如果定义的变量是准备在将来用来保存对象的,那么最好就可以把变量初始化为null
。这样一来只需要去检查null值就知道相应的变量是否已经保存了一个对象的引用。
实际上undeifined
值是派生自null
的,所以ECMA-262规定对他们的相等性测试要返回true:
alert(undeifined == null); //true |
**==
相等操作符会为了比较的目的,会对操作数进行转换,后面会详细介绍
尽管null
和undefined
有这样的关系,但是他们的用途是完全不一样的。
- 在任何情况下,都没有必要把变量初始化成
undefined
; - 但只要是意在保存变量却还没有真正保存对象时,应该明确的让对象保存
null
Boolean
类型
Boolean
类型是使用的最多的一种类型,该类型有两个字面值:true
,false
。虽然字面值只有两个,但是ECMAScript中所有的类型的值都有与这两个值等价的值,要将一个值转换为等价的Boolean
值只需要调用转型函数Boolean()
,转换规则如下:
数据类型 | 转换为true的值 | 转换为false的值 |
---|---|---|
Boolean | true | false |
Srting | 非空字符串 | “”(空字符串) |
Number | 任何非零数字 | 0,NaN |
Object | 任何对象 | null |
Undefined | n/a | undefined |
在if
语句中也会按照这个规则进行自动转换
Number
类型
整数
var intNum = 44; //整数 |
浮点数值
var floatNum1 = 1.9; |
由于保存浮点的空间是整数的两倍,所以ECMAScript会不失时机的把能转换成整数的浮点数转成整数
浮点数值的精确度是17位小数,进行算术计算的适合精度远远不如整数,所以不要去测试某个特定的浮点数
|
数值范围
由于内存的限制,ECMAScript并不能保存所有的数值,是有一定的范围的,超出这个范围将会被转换成Infinity
(正无穷)或者-Infinity
(负无穷),因为正负无穷都是不能参与计算的,要确定一个值是否是有穷的,可以通过isFinite()
函数来判断:
var min = Number.MIN_VALUE; //能保存的最小值 |
NaN
NaN
(Not a Number),是一个特殊的数值,表示本来要返回数值的的操作数却返回了不是数值的情况,这样就不会抛出错误。比如其他语言在遇到除以0的时候都会导致错误而停止代码执行,但是ECMAScript中不会停止代码执行,会返回相应的值:
alert(100/0); //Infinity |
NaN
有两个特点:
- 凡是NaN参与的运算都返回
NaN
- NaN和任何值都不相等,包括
NaN
本身(你不能保证两个都不值数值的值是相等的)
针对这两个特点,ECMAScript定义了isNaN()
函数,接受一个参数,判断参数是不是NaN
。在接收到一个值时,会尝试将参数转换为数值。有些值虽然本身不是数值,但是是可以转换成数值的,就像"100"
, true
就可以转换成数值100
和1
。对于不能被转换成数值的值就会导致isNaN()
返回true
,其他则返回false
。
数值转换
有三个函数可以把非数值转换成数值:
Number()
: 把任意类型转换成数值parseInt()
: 把字符串转换成整数parseFloat()
: 把字符串转成换浮点数
Number()
的转换规则:
- 如果是
Boolean
,true
和false
分别转成1
和0
; - 如果是
Number
,只是简单的传入和传出; - 如果是
null
,返回0
; - 如果是
undefined
,返回NaN
; - 如果是字符串,遵守下面的规则:
- 如果只包含数字(包括前面的正负号),转换成对应的十进制数值
- 如果包含有效的浮点格式,转换成对应的浮点格式数值
- 如果包含有效的十六进制的格式,转换为相同大小的十进制数值
- 如果为空,转换为
0
- 如果包含上述格式之外的字符,转换为
NaN
- 如果是对象,调用对象的
valueOf()
方法,然后按照前面的规则转换返回值,如果转换的结果为NaN
,则继续调用对象的toString()
方法,在按照字符串规则转换返回值。
因为Number()
转换规则很复杂,并且转换字符串的适合有不合理的地方,所以一般更多的采用parseInt()
来处理字符串转成数值。parseInt()
的规则是:忽略掉前面的空格,直到找到第一个非空字符,如果第一个非空字符串不是数字或者正负号,则直接返回NaN,也就是空字符串也会返回NaN,但Number()
会返回0。如果第一个非空字符是数字或者正负号,则继续解析第二个字符,直接解析完或者遇到非数字字符,例如"1234abcd"
会被转换成1234
,"12.2"
会转换成"12"
,因为小数点也不是有效的数字字符。
parseInt()
可以指定第二个参数来作为进制数
和parseInt()
函数类似,parseFloat()
也是从第一个字符开始一直解析到字符串尾,或者遇到一个无效的浮点数字字符为止。也就是说第一个小数点是有效的,而之后的小数点就是无效的。
String
类型
String
类型表示由零或多个16位Unicode字符组成的字符序列,即字符串。字符串可以用单引号或者双引号来表示。
字符串的不可变性
字符串一但创建就是不可变的,如果要改变某个变量保存的字符串,首先销毁掉原来的字符串,然后再用一个包含新值的字符串来赋值给该变量。
转换为字符串
把一个值转换成字符串有两种方法:
- 几乎每个值都有
toString()
方法,除了null和undefined - 转型函数
String()
null
返回"null"
`undefined
返回"undefined"
- 其他返回
toString()
的返回值
Object
类型
ECMAScript中的对象其实就是一组数据和功能的集合。对象通过new
操作符后跟要穿件的对象类型的名称来创建。而创建Object
类型的实例并为其添加属性或方法,就可以创建自定义的对象。
在ECMAScript中,Object
类型是所有它的实例的基础,也就是Object
类型所具有的任何属性和方法也同样存在于更具体的对象中。每个Object
实例都具有以下属性和方法:
- constructor:构造函数,也就是创建当前对象的函数
hasOwnProperty(propertyName)
:检测给定属性在当前实例中(不是实例的原型中)是否存在isPrototypeOf(Object)
:检测当前对象是否是传入对象的原型propertyIsEnumerable(propertyName)
:检测给定属性是否能使用for-in
语句来枚举toLocalString()
:对象的字符串表示,与执行环境的地区对应toString()
:对象的字符串表示valueOf()
:对象的字符串、数值或布尔值的表示,通常和toString()
返回的相同