数字
** 整形直接量**
在 js 中用一个数字序列表示一个整数,除了十进制的直接量还能是别十六进制的值所谓十六进制的直接量是指以"0x"或"0X"为前缀,其后跟随十六进制数传的直接量.十六进制是09之间的数字和工(A)地(F)之间的字母构成,a~f 对应的事10~15
例如
oxff//15*16+15=255(十进制)
OxCAFE911
0377//3*64+7*8+7=255
浮点型直接量
浮点型直接量可以含有小数,采用的是传统的实数写法,一个实数由实数部分小数点小数部分组成,还可以使用指数记数法表示浮点型直接量,即使实数后面跟字母e或E再跟正负号在加一个整形的指数.这种方法的表示数值是由前面的实数乘以十的指数次幂.
更简洁的语法表示
[digits] [.digits] [(E|e)[(+|-)]digits]
例如
3.14
2345.789
.3333333333333333
6.02e23
1.4738223E-32
js 中的算数运算
js 中的算数运算在溢出 下溢或被零整除时不会报错
溢出:结果为一个特殊的无穷大值,在 js 中以 infinity 表示 同样地,当负数的值超过了 js 所表示的复数范围,结果是负无穷大在 js 中以-infinity 表示.
下溢:适当运算结果无线接近于零并比 js 能表示的最小值还小的时候发生的一种情形.
被零整除时在 js不汇报错: 它只是简单的返回无穷大或负无穷大(infinity).
js 中的非数字值有一点特殊:它的任何值都不想等,包括自身.也就是说没办法通过 x==NaN 来判断变量 x 是否是 NaN.
文本
字符串是一组由16位值组成的不可变的有序虚列,每个字符通常来自于 unicode 字符集.js 通过字符串类型来表示文本.
字符串直接量
在 js程序中的字符串直接量,是由单引号或双引号括起来的自序序列由单引号定界的字符串中可以包含双引号,由双引号包含的字符串中也可以包含单引号.
例子:
""//空字符串:它包含0个字符
'testing'
"3.14"
'name=myform'
"wouldn't you prefer O 'Reilly's book?"
"This string
has two lines"
"π is the ratio of a circle's circumference to its diameter"
转义字符
在 js 中字符串中反斜线()有这特殊的用途,反斜线符号后加一个字符,就不在表示他们的字面含义了,比如 就是一个转义字符,它表示一个换行符
字符串的使用
js 的内置功能之一就是字符串链接.如果将加号(+)运算符用于数字,表示两数想加.但将它的作用于字符串,则表示字符串链接,将第二个字符串拼接在第一个之后
例如:
msg + "Hello, " + "world";//生成字符串 "Hello,world"
greeting = "Welcome to my blog," + ' " + name;
要确定一个字符串的长度 其所包含的16位值的个数 可以使用字符串的 length 属性.比如,要得到字符串 s 的长度
s.length
在 ECMAScript5中,字符串可以当做只读数组除了使用 charAT()方法,也可以使用括号来访问字符串中的单个字符(16位值) :
s = "hello, world";
s[0] //=> "h"
s[s.lenght-1] //=> "d"
模式匹配
布尔值
布尔值指代真或假 开或关 是或否.这个类型的两个值,保留字true 和false.
js 程序中的比较语句的结果通常都是布尔值,例如:
a==4
这段代码用来检测变量 a 的值是否等于4.如果等于,比较结果的布尔值就是 true;如果不等,比较结果则为 false
null 和 undefined
null是 js 的关键语言他表示一个特殊值,长用来描述"空值".
undefined是预定义的全局变量,它的值就是"未定义".
全局对象
全局对象在 js 中有这重要的用途:全局对象的属性是全局定义的符号,js 程序可以直接使用.当 js 解释器启动时(或者任何 web 浏览器加载新页面的时候),他讲创建一个新的全局对象,并给它一组定义的初始属性
全局属性:比如 undefined infinity和 NaN
全局函数:比如isNaN() parseInt() 和evsl()
构造函数:比如 Date() RegExp() String() Object()和 Array()
全局对象:比如 Math 和 JSON
包装对象
js 对象是一种复合值:它是属性或已命名值的集合.通过"." 符号来引用属性值.当属性值是一个函数的时候,称其为方法.通过 o.m()来调用对象 o 中的方法.
我们看到字符串也同样具有属性和方法;
var s = "hello world!"; //一个字符串
var word = s.substring(s.index0f("")+1, s.length); //使用字符串的属性
不可变得原始值和可变的对象引用
js 中的原始值与对象有这根本的区别.原始值是不可更改的一个原始值.对数字和布尔值来说显然如此 改变数字的值本身就说不通,而对字符串来说就不那么明显了,因为字符串看起来像由字符组成的数组,我们期望可以通过指定索引来修改字符串中的字符.实际上,js 是禁止这样做的.字符串总所有的方法看上去返回了一个修改后的字符串,实际上返回的时一个新的字符串,实际上返回的是一个新的字符串值.
例如:
var s = "hello"; //定义一个由小写字母组成的文本
s.touppercase(); //返回"HELLO",但并没有改变 s 的值
s // =>"hello":原始字符串的值并未改变
对象和原始不同,首先,他们是可变的 他们的值时刻修改的:
var o = {x:1}; //定义一个对象
o.x = 2; //通过修改对象属性值来更改对象
o.y =3; //再次更改这个对象,给它增加一个新属性
var a = [1,2,3] //数组也是可修改的
a[0] =0; //更改数组的一个元素
a[3] = 4; //给数组增加一个新元素
对象的比较并非值的比较:即使两个对象包含相同的属性及相同的值,它们也是不想等的.各个索引元素安全相等的两个数组也不相等.
var o = {x:1}, p = {x:1}; //具有相同属性的两个对象
o === p //=>false: 两个单独的对象永不相等
var a = [], b = []; //两个单独的空数组
a === b //=>false: 两个单独的数组永不相等
我们通常将对象称为引用类型,以此来和 js 的基本类型区分开来.依照术语的叫法,对象值都是引用,对象的比较均是引用的比较:当且仅当它们引用同一个基对象时,它们才想等.
var a = []; //定义一个引用空数组的变量 a
var b = a; //变量 b 引用同一个数组
b[0] = 1 //通过变量 b 来修改引用的数组
a[0] // => 1: 变量 a 也会修改
a === b // => true:a 和 b 引用同一个数组,因此它们想等
下面的例子则是通过循环来完成数组复制:
var a = ['a','b','c']; //待复制的数组
var b = []; //复制到的目标空数组
for(var i = 0; i < a .length; i++) { //遍历 a[]中的每个元素
b[i] = a[i]; //将元素值复制到 b 中
}
如果我们相比较两个单独的对象或者数组,,则必须比较它们的属性或元素.下面这段代码定义了一个比较两个数组的函数:
function equalArrays(a,b) {
if (a.length != b.length) return false; //两个长度不同的数组不想等
for(var i = 0; i < a .length; i++) //循环遍历所有元素
if (a[i] !== b[i]) return false; //如果有任意元素不等,则数组不想等
return true; //否则它们相等
}
类型转换
转换和相等性
由于 js 可以做灵活的类型转换,因此其"=="相等运算符也随相等的含义灵活多变.
例如,如下这些结果均是 true:
null == undefined //这两值被认为相等
"0" == 0 //在比较之前字符串转换成数字
0 == false //在比较之前布尔值转换成数字
"0" == false //在比较之前字符串和布尔值都转换成数字
显示类型转换
尽管 js 可以做很多类型的转换,但有时扔需要做显示转换,或者为了使代码变得更清晰易读而做的显示转换.
做显示类型转换最简单的方法就是使用 Boolean() Number() String()或 Object()函数.
Number("3") //=> 3
String(false) //=> "false"或使用 false.toString()
Boolean([]) //=> true
Object(3) //=> new Number(3)
代码中经常会出现这种类型转换的惯用法:
x+"" //等价于String(x)
+x //等价于 Number(x).也可以写成 x-0
!!x //等价于 Boolean(x).注意是双叹号
对象转换为原始值
Reg Exp类(Reg Exp class) 定义的 toString()方法讲 Reg Exp 对象转换为表示正则表达式直接量的字符串
[1,2,3].toString() //=>"1,2,3"
(function(x) {f(x); }).tiString() //=>"function(x) {
f(x);
}"
八 d+/g.toString(0 //=>"八d+/g"
new Date(2010,0,1).toString() //=>"Fri Jan 01 2010 00:00:00 GMT-0800(PST)"
变量声明
变量是使用关键字 var 来声明的如下所示:
var i;
var sum;
可以通过 var 关键字来声明多个变量:
var i,sum;
而且还可以将变量的初始赋值和变量声明和写在一起:
var message = "hello";
var i = 0 , j = 0, k = 0;
在 for 和 for/in 循环中同样可以使用 var 语句,这样可以更简洁地声明在循环体语法内中使用的循环变量.例如:
for(var i = 0; i < 10; i++)console.log(i)
for(var i = 0; j = 10; i < 10; i++,j--) console.log(i*j);
for(var p in o) console.log(p);
js 变量可以是任意数据类型.例如,在 js 中首先将数字赋值给一个变量,随后再将字符串赋值给这个变量,这是完全合法的
var i = 10;
i = "ten";
应该始终使用 var来声明变量
变量作用域
在函数体内,局部变量的优先级高于同名的全局变量.如果在函数内声明的一个局部变量或者函数参数中带有的变量和全局变量重名,那么全局变量就被局部变量所遮盖.
var scope = "global"; //生命一个全局变量
functioon checkscope() {
var scope = "local"; //声明一个同名的局部变量
return scope; //返回局部变量的值,而不是全局变量的值
}
checkscope() //=>"local"
尽管再全局作用域编写代码时可以不写 var 语句,但声明局部变量时则必须使用 var 语句.思考一下如果不这么做会怎样:
scope ="global"; //声明一个全局变量,甚至不用 var 来声明
function checkscope2(){
scope = "local"; //糟糕!我们刚修改了全局变量
myscope = "local"; //这里显示地声明了一个新的全局变量
return [scope, myscope]; //返回两个值
}
checkscope2() // => ["local","local"]:产生了副作用
scope //=> "local":全局变量修改了
myscope //=>"local":全局命名空间搞乱了
函数定义是可以签套的.由于每个函数都有它自己的作用域,因此会出现几个局部作用域嵌套的情况,例如:
var scope = "global scope"; //全局变量
function checkscope() {
var scope = "local scope"; //局部变量
function nested(){
var scope = "nested scope"; //嵌套作用域内的局部变量
return scope; //返回当前作用域的值
}
return nested();
}
checkscope() // => "嵌套作用域"
函数作用域和声明提前
在如下所示的代码中,在不同位置定义了变量 i j 和 k,它们都在同一个作用域 这三个变量在函数日内均是有定义的.
function test(o) {
var i =0; //i 在整个函数体内均是有定义的
if (typeof o == "object") {
var j = 0; //j 在函数体内是有定义的,不仅仅是在这个代码段内
for(var k=0; k < 10; k++) { //k的函数体内是有定义的,不仅仅是在循环内
console.log(k); //输出数字0~9
}
console.log(k); //k已经定义了,输出1
}
console.log(j); //j 已经定义了,但可能没有初始化
}
作为属性的变量
当声明一个 js 全局变量的时候,实际上是定义了全局对象的一个属性.当时用 var 声明一个变量时,创建的这个属性是不可配置的,也就是说这个变量无法通过delete 运算符删除.可能你已经注意到了,如果你没有使用严格的模式并给一个未声明的变量赋值的话,js 会自动创建一个分局变量.以这种方式创建的变量是全局对象的正常的可配指值属性,并可以删除它们:
var truevar = 1; //声明一个不可删除的全局变量
fakevar = 2; //创建全局对象的一个不可删除的属性
this.fakevar2 = 3; //同上
delete truevar // => false: 变量并没有被删除
delete fakevar // => true: 变量被删除
delete this.fakevar2 // => true: 变量被删除