计算机程序的运行需要对值(value)比如数字3.14或者文本"hello world"进行操作,在编程语言中,能够表示并操作的值的类型叫做数据类型(type),编程语言最基本的特性就是主持多种数据类型。当程序需要将值保持起来以备将来使用时,便将其赋值给(将值“保存”到)一个变量(variable)。变量是一个值的符号名称,可以通过名称获得对值的引用。变量的工作机制是编程语言的令一个基本特性。本章将参照上节帮助理解本章内容,后续将更深入的讲解。
Javascript的数据分为两类:原始类(PRimitive type)和对象类型(object type)
javascript中的原始类包括数字,字符串,布尔值,本章会有单独的章节专门讲述javascript的数字、字符串、布尔值。javascript还有两个特殊的原始值,null(空)和Undefined(未定义),他们不是数字、字符串、布尔值。它们分别代表了各自特殊类型的唯一成员。
javascript除了数字、字符串、布尔值、null、undefined之外就是对象了。对象 (object)是属性(property)的集合。每个属性都由"名/值对"(值可以是原始值,比如数字,字符串,也可以是对象)构成。其中一个比较特殊的对象(全局对象(global object)会在第五小姐介绍,第六小节将更详细的描述)
普通的javascript对象是“命名值”的无需集合。javascript同样定义了一种特殊对象--数组(array),表示带编号的值的有序集合。javascript为数组定义了专用的语法。使数组拥有一些和普通对象不同的特有的行为属性。
javascript还定义了一种特殊的对象--函数。函数是具有与它想关联的可执行代码的对象,通过调用函数来运行科执行代码,并返还运算结果。和数组一样,函数行为特征和其它对象都不一样。javascript为使用函数定义了专用语法。对javascript函数来讲。最重要的是,他们都是真值,并且javascript可以讲他们当做普通对象来对待。
如果函数初始化(使用new运算符)一个新建对象,我们称之为构造函数(constructor)。每个构造函数定义了一类(class)对象--构造函数初始化对象组成的集合。类可以看做对象类型的子类型。除了数组(array)类和函数(function)类之外,javascript还定义了其它三种由用的类。日期(date)定义了代表日期的对象。正则(regExp)定义了正则表达式的对象。错误(error)类定义了那行表示javascript程序中运行时错误和语法错误对象。可以通过定义自己的构造函数来定义需要的类。
javascript解释器有自己的内存管理机制,可以自动对内存进行垃圾回收(garbagecollection)。这意味着程序程序可以按需创建对象,程序员则不必担心这些对象的销毁了内存回收。当不再有任何一个引用指向一个对象,解释器就知道这个对象没有用了,然后会自动回收它所占用的内存资源。javascript是一种面向对象的语言。不严格的讲,这意味着我们不用全局的定义函数去操作不同类型的值,数据类型本身可以定义方法(method)来使用值,例如要对数组a中的元素进行排序,不必要将a传入sort()函数,而是调运a的一个方法sort()
a.sort(); //sort(a)面向对象的版本
从技术上来将,只有javascript对象才能拥有方法。然而,数字,字符串,布尔值也拥有自己的方法。在javascript中,只有null和undefined是无法拥有方法的值。
javascript的类型可以分为原始类型和对象类型,可分为可以拥有方法的类型和不能拥有方法的类型。同样可分为可变(mutable)和不可变(immutable)类型。可变类型的值是可以修改的,对象和数组属于可变类型:javascript程序可以改变对象的属性值和数组元素的值。
数字、布尔值、null和undefined属于不可改变的类型。比如,修改一个数组的内容本身就说不通。字符串可以看做是字符组成的数组,你可以认为它是可以变的。然而在javascript中,字符串是不可变的。可以访问字符串任意位置的文本,但javascript并未提供修改一直字符串文本内容的方法。
javascript可以自由地进行数据类型转换。比如,如果在程序期望使用字符串的地方使用了数字,javascript会自动将数字转换为字符串。如果期望在使用布尔值的地方使用了非布尔值,javascript也会相应的转换。javascript中对灵活的类型抓换规则对“判断相等”(equality)
javascript的变量是无类型的(untyped),变量可以被赋予人和类型的值,使用var关键字来声明(declare)变量。javascript采用语法作用域,不在任何函数内声明的变量称为全局变量(global variable),它在javascript的程序 中任何地方都是可见的。
1.数字
和其它编程语言不同,javascript不区分整数数值和浮点数数值。javascript中的数值均用浮点数数值来表示。当一个数字直接出现在javascript程序中,我们陈之为数字直接量(numeric literal),javascript支持多种格式的数字直接量。(注意:在任何数字前直接添加负号(-)可以得到它们的负值)但负号是一元求反运算符。,并不是数字直接量语法的组成部分。)
i整数型直接量
javascript中用一个数组序列表示一个十进制的整数
除了十进制的整数直接量,javascript同样识别十六机制(16)为基数的的值。所谓十六进制是以“0X”或者"0x"为前缀,其后紧跟十六进制数串的直接量。十六进制数值是0-9的数字和a(A)-f(F)之间的字母构成。a-f的字母对于的表述数字10-15下面是十六进制整型直接量的例子
0xff //15*16+15=2550xCAFE911
尽管ECMAScript不支持八进制直接量,但javascript的某些实现可以允许采用八进制(基数为8)形式表示整数。八进制直接量以数字0开始,其后跟随着一个0-7之间数字组成的序列。
0377 // 3*64 +7*8 +7 =255(十进制)
由于某些javascript的实现支持八进制的之间量,而有些不支持,因此最好不要使用以0为前缀的整数之间量,毕竟我们也无法得知当前javascript的实现是否支持八进制的解析。在ECMAScript6的严格模式下,八进制的直接量是明令禁止的。
ii.浮点型直接量
浮点型直接量可以含有小数点,它们采用的是传统的实数写法。一个实数由整数部分,小数点和小数部分组成。
此外,还可以使用指数计数法表示浮点型直接量。即在实数后跟字母E或e,后面再跟正负号,其后再加一个整型的指数。这种计数方法表示的数值,是有前面的实数乘以10的指数幂。可以使用更简洁的语法来表示
[digits][.digits][(E|e)[(+|-)]digits]
3.14 2345.455 .33333333333333333 6.02e23 //6.02*10的23次方 1.255454E-23 //1.255454*10的负23次方
iii.javascript中的算术运算
javascript程序是使用语言本省提供的算术运算符来进行数字运算的的。这些运算符包含+ - * /和求余(整除后的余数)运算符%除了基本的运算符之外,javascript还支持更加复杂的算术运算,这个线复杂的运算通过作为Math对象的属性定义的函数和常量实现。
Math.pow(2, 53) //=>9007199254740992 document.write(Math.pow(2,53) ) Math.round(.6) //=>1.0 四舍五入 Math.ceil(.6) //=>1.0向上求整 Math.floor(.6) //=>0.0向下求整 Math.abs(-5) //=>5 求绝对值 Math.max(x, y, z) //返回最大值 Math.min(x, y, z) //返回最小值 Math.random() //生成一个大于0小于1的伪随机数 Math.PI //圆周率π Math.E //e:自然对数的底数 Math.sqrt(3) //3的平方根 Math.pow(3, 1 / 3) //3的立方根 Math.sin(0) //三角函数,还有Math.cos,Math.atan等 Math.log(10) //=>2.302585092994046 以10为底的自然对数 Math.log(512) / Math.LN2 //以2为底的512的对数 Math.log(100) / Math.LN10 //以10为底的100的对数 Math.exp(3) //e的三次幂
javascript中的算术运算在溢出(overflow)、下溢(underflow)或被零整除时不会报错。但数字运算结果超过了javascript中所能表示的数字上线(溢出),结果为一个特殊的无穷大的值(infinty)值,在javascript中以infinty表示。同样地,当负数的值超过了javascript所能表达的负数范围,结果为负无穷大,在javascript中以-Infinty表示。无穷大值的行为特性和我们所期望的是一致的:基于它们的加减乘除运算结果是无穷大(保留正负号)
下溢(underflow)是当运算结果无线接近于零并比 javascript能表示的最小值还小的时候发生的一种情形。当一个负数发生下溢时,javascript返回一个特殊的值,“负零”,这个(负零)几乎和正常的零完全一样。javascript程序员很少用到负零。
javascript预定义了全局变量Infinaty和NaN,用来表达正无穷大河非数字值,在ECMAScipt3中,这两个值是可以读写的。ECMAScript5修正了这个问题,将他们定义为只读的。ECMAScipt3中的Number对象定义的属性值也是只读的,这里有一些例子:
Infinity //将一个可读/写的变量初始化为infinty Number.POSITIVE_INFINITY //同样的值,只读 1 / 0 //这也是同样的值 Number.MAX_VALUE + 1 //计算结果还是Infinity Number.NEGATIVE_INFINITY //表示了负无穷大 -Infinity -1/0 -Number.MAX_VALUE -1 NaN //将一个可读/写的变量初始化为NaN Number.NaN //同样的值,但是只读 0/0 //计算结果还是NaN Number.MIN_VALUE/2 //发生下溢。计算结果为0 -Number.MIN_VALUE/2 //负零 -1/Infinity //负零 -0 //负零
javascript中的非数字值有一点特殊,它和人和值都不相等,包括自身。也就是说没法通过x==NaN来判断x是否为NaN。相反,应当使用x!=x来判断,当且仅当x为NaN的时候,表达式的结果为true.函数isNaN()作用与此相似,如果参数是NaN或者是一个非数字值(比如字符串和对象),则返回true。javascript中有一个类似的函数isFinite(),在参数不是NaN、Infinty或-Infinity的时候返回true.
负零值同样有些特殊,它和正负零是相等的(甚至使用javascript的严格相等测试来判断)、这意味这两个值几乎是一模一样的,除了作为除数之外:
var zero = 0; var negz = -0; zero === negz //=>true 正负零值相等 1/zero === 1/negz //false 正无穷大和负无穷大不等
iiii.二进制浮点数和四舍五入错误
实数有无数个,但javascript通过浮点数的形式只能表示有限的个数(确切的说有18 437 736 874 454 810 627个),也就是说,当javascript中使用实数的时候,常常只是真实值的一个近似的表示。
javascript采用了IEEE-754浮点数表示法(几乎所有的现代编程语言采用)。这是一种二进制表示法,可以精确的表示分数,比如1/2 1/8 和1/1024,遗憾的是,我们常采用的分数,特别是金融计算方面,都是以十进制分数1/10 ,1/100等。二进制表示法并不能表示类似0.1这样简单的数字。
javascript中的数字具有足够的精度。并可以接近0.1.但事实上,数字不能精确表述带来了一些问题。
var x = .3 - .2; var y = .2 - .1; alert(x == y) //=>false 两值不相等 x == .1 //=>false .3-.2 不等于.1 y == .1 //=>true .2-.1等于1
由于舍入误差,0.3和0.2之间的近似差值实际上并不等于0.2和0.1之间的近似差值(在真实模拟环境中,0.3-0.2=0.099 999 999 999 999 98).这个问题不只在javascript中存在,理解这一点十分重要:在任何使用二进制浮点数的编程语言中都会有这个问题。同样需要注意的是,上述代码中x和y的值非常接近彼此和最终的正确值。这种计算结果可以胜任大多数的计算任务。这个问题也是只有比较两个值是否相等的时候才才会出现。
javascript的未来版或许支持十进制数字类型以避免这个问题,在这之前你可能更愿意使用大整数进行重要的金融计算。例如,要使用整数“分”,而不要使用小数“元”进行基于货币单位的运算。
iiiii.日期和时间
javascript语言核心包含Date()构造函数,原来创建日期和时间的对象,这些日期对象的方法为日期计算提供了简单的API,日期对象不能像数字那样是基本数据类型。
var zhen = new Date(2011, 0, 1); //2011年1月1日 var later = new Date(2011, 0, 1, 17, 10, 30); //同一天 var now = new Date(); //当前的日期和时间 var elapsed = now - zhen; //日期减法。计算时间间隔的毫秒数 later.getFullYear(); //=>2011 later.getMonth(); //=>0 从0开始计数的月份 later.getDate(); //=>1 从1开始计数的天数 later.getDay(); //=>5 得到星期几。 0代表星期日,5代表星期1 later.getHours() //=>当地时间 later.getUTCHours() //使用UTC表示小时的时间,基于时区。
2.文本
字符串(string)是一组16位值组成的不可变的有序序列,每个字符通常来自于Unicode字符集。javascript通过字符串类型来表示文本。字符串的长度(length)是其所含的16位值的个数。javascript字符串(和其数组)的索引从0开始。空字符串的(empty string)长度为0,javascript中并没有表示单个字符的“字符型”。要表示一个16位值,只需要将其赋值给字符串变量即可。这个字符串的长度为1。
字符集,内码和javascript字符串javascript采用UTF-16编码的Unicode字符集,javascript字符串是由一组无序号的16位值组成的序列。最常用的Unicode字符都是通过16位的内码表示,并代表字符串中的单个字符,那行不能表示为16位的Unicode字符则遵循UTF-16编码规则----用两个16位值组成一个序列(亦称为“代理项对”)表示。这意味着一个长度为2的javascript字符串(两个16位值)可能表示一个Unicode字符。var p ="π" ; //π由16位内码表示0x03c0var e = "e"; //e由17位内码表示0x1d452p.length // =>1 p包含一个16位的值e.length // =>2 e通过UTF-16编码后包含两个值:"/ud835/udc52"javascript定义的各式字符串操作方法均作用于16位值,而非字符,且不会对代理项对做单独处理。同样javascript不会对字符串做标准化的加工。甚至不能保证字符串是合法的UTF-16格式
i字符串直接量
在javascript程序中的字符串直接量,是由单引号或双引号括起来的字符序列,由单
新闻热点
疑难解答