JS基础知识回顾:ECMAScript的语法(二)

ECMAScript中有五种简单数据类型(也称为基本数据类型):Undefined、Null、Boolean、Number、String

ECMAScript还有一种复杂数据类型——Object,Object本质上是由一组无序的名值对组成的。

ECMAScript不支持任何创建自定义类型的机制,而所有值最终都将是上述六种数据类型之一,由于ECMAScript的数据类型具有动态性,因此的确没有再定义其他数据类型的必要了。

监狱ECMAScript是松散类型的,因此需要有一种手段来检测给定变量的数据类型,typeof就是负责提供这方面消息的操作符。

typeof的操作数可以是变量也可以是数值字面量,typeof是一个操作符而不是函数,所以在使用时可以加圆括号也可以不加。

对一个值使用typeof操作符可能返回下列某个字符串:

"undifined"——该值未定义

"boolean"——该值为布尔型

"string"——该值为字符串

"number"——该值为数值

"object"——该值为对象或null(特殊值null被认为是一个空的对象引用)

"function"——该值为函数(Safari5以及之前的版本、Chrome7以及之前的版本对正则表达式调用typeof操作符时会返回"function",其他浏览器则返回"object")

从技术的角度来讲,函数在ECMAScript中是对象,不是一种数据类型,然而函数也确实有一些特殊的属性,因此通过typeof操作符来区分函数和其他对象是很有必要的。

Undefined类型只有一个值,即特殊的undefined,在使用var声明变量但未对其进行初始化时,这个变量的值就是undefined。

一般而言,不需要显示地把一个变量设置为undefined,字面值undefined通常用于比较,在ECMA-262第三版之前并没有这个值,第三版引入它的目的是为了正式区分空对象指针与未经初始化的变量。

对于尚未声明过的变量只能执行一项操作,即使用typeof操作符检测其数据类型(对未经声明的变量调用delete不会导致错误,但并没有实际意义)。

对于尚未声明过的变量调用typeof操作符也会返回undefined值,尽管它和未初始化的值有本质上的区别。

即便未初始化的变量会自动被赋予undefined值,但显示地初始化变量仍然是明智的选择,如果能够做到这一点,那么当typeof操作符返回undifined值时,就能够知道该变量是未被声明,而并不是尚未初始化。

Null类型只有一个值,即特殊的null,从逻辑角度来看,null值表示一个空对象指针,而这也正是使用typeof操作符检测null值时会返回object的原因。

如果定义的变量准备在将来用于保存对象,那么最好将该变量初始化为null而不是其他的值,这样一来,只要直接检查null值就可以知道相应的变量是否已经保存了一个对象的引用。

实际上undefined值是派生自null值的,因此ECMA-262中对于二者的相等性测试返回的是true,尽管有这样的关系,但它们的用途完全不同。

只要意在保存对象的变量还没有真正保存对象,就应该明确的让该变量保存null值,这样做不仅可以体现null作为空对象指针的惯例,也有助于进一步区分null和undefined。

Boolean类型是ECMAScript中用的最多的一种类型,该类型只有两个字面值:"true"和"false"。

Boolean类型的字面量是区分大小写的,并且ECMAScript中所有类型的值都有与这两个Boolean值等价的值。

要将一个值转换为其对应的Boolean值,可以调用转型函数Boolean(),各种数据类型及其对应的转换规则如下:

Boolean:true(返回true)、false(返回false)

String:任何非空字符串(返回true)、""(返回false)

Number:任何非零数值/包括无穷大(返回true)、0和NaN(返回false)

Object:任何对象(返回true)、null(返回false)

Undefined:n/a(返回true)、undefined(返回false)——n/a是not applicable的缩写,意思是“不适用”

这些转换规则对于理解控制流语句自动执行相应的Boolean转换非常重要,错误的使用一个对象而不是Boolean值就有可能彻底改变应用程序的流程。

Number类型使用了IEEE754格式来表示整数和浮点数值,为了支持各种数值类型,ECMA-262定义了不同的数值字面量格式:

十进制字面值(在进行算术运算时,所有以八进制和十六进制表示的数值最终都将被转换成十进制数值)

八进制字面值(第一位为0,后面为八进制数字序列0-7,若该序列超出八进制范围则将被省略前导零看做十进制整数,八进制整数在严格模式下无效,会导致支持的JavaScript引擎抛出错误)

十六进制字面值(前两位为0x,后跟十六进制数字0-9和A-F,字母大小写随意)

鉴于JavaScript保存数值的方式,可以保存正零(+0)和负零(-0),正零和负零被认为相等。

浮点数值当中必须包含一个小数点,并且小数点后面必须至少有一位数字,小数点前可以没有整数,但并不推荐这种写法。

由于保存浮点数值需要的内存空间是保存整数值的两倍,因此ECMAScript会不失时机的将浮点数值转换为整数值:小数点后无数字、浮点数本身表示的是整数。

也可以用科学计数法表示的浮点数值来表示极大或极小的数值,用科学计数法表示的数值等于e前面的数值乘以10的指数次幂,此处的e大小写随意。

浮点数值的最高精度是17位小数,但基于IEEE754数值的浮点计算普遍存在计算不准确的问题,所以永远不要测试某个特定的浮点数值。

由于内存的限制,ECMAScript并不能保存所有的数值。

ECMAScript能够表示的最小数值保存在Number.MIN_VALUE中,在大多数浏览器中这个值是5e-324。

ECMAScript能够表示的最大数值保存在Number.MAX_VALUE中,在大多数浏览器中这个值是1.7976931348623157e+308。

如果某次计算结果超出该范围,则那个数值将被自动转换成特殊的Infinity值,若为正数则返回Infinity(正无穷),若为负数则返回-Infinity(负无穷)。

访问Number.NEGATIVE_INFINITY和Number.POSITIVE_INFINITY可以得到-Infinity和Infinity。

如果想要确认某个数值是否在正负无穷的范围内,可以使用isFinite()函数,如果这个函数的参数在正负无穷之间会返回true。

NaN即非数值(Not a Number)是一个特殊的数值,这个数值用于表示一个本来应该返回数值的操作数未返回数值的情况(这样就不会抛出错误了)。

在其他编程语言中,任何数值除以0都会导致错误,而在ECMAScript中会返回NaN,因而不会影响其他代码的执行。

任何涉及NaN的操作都会返回NaN,这个特点在多步计算中有可能导致问题,NaN与任何值都不相等,包括它本身。

针对以上特点ECMAScript定义了isNaN()函数,这个函数接受一个参数后将尝试将其转换为数值,如果无法转换为数值则会返回true:

alert(isNan(NaN));//true

alert(isNan(10));//false(数值10)

alert(isNan("10"));//false(可以被转换为数值10)

alert(isNan("blue"));//true(无法转换为数值)

alert(isNan(true));//false(可以被转换为数值1)

isNaN()同样适用于对象,在基于对象调用该函数时,会首先调用对象的valueof()方法,然后确定能否返回数值,若不能,将基于该返回值再次调用toString()方法,再测试返回值,这个过程也是ECMAScript中内置函数和操作符的一般执行流程。

有三个函数可以把非数值转换为数值:Number()、parseInt()、parseFloat()。

第一个函数可以用于任何数据类型,而另外两个函数则专门用于把字符串转换成数值。

Number()函数的转换规则如下(一元加操作符的操作与该函数相同):

如果是Boolean值,true和false将分别转换为1和0;

如果是数字值,只是简单的传入和返回;

如果是null值,返回0;

如果是undefined,返回NaN;

如果是字符串,遵循下列规则:

  如果字符串中只包含数字(包括前面带正号或负号的情况),则将其转换为十进制数值(忽略前导0)

  如果字符串中包含有效的浮点格式,则将其转换为浮点数值(忽略前导0)

  如果字符串中包含有效的十六进制格式,则将其转换为相同大小的十进制整数值

  如果字符串是空的,则将其转换为0

  如果字符串中包含除上述格式之外的字符,则将其转换为NaN

如果是对象,则调用对象的valueOf()方法,然后依照前面的规则转换返回的值,如果转换的结果是NaN,则调用对象的toString()方法,然后再次依照前面的规则转换返回的字符串值。

由于Number()函数在转换字符串时比较复杂而且不够合理,因此在处理整数的时候更常用的是parseInt()函数。

parseInt()函数在转换字符串时,更多的是看其是否符合数值模式,它会忽略字符串前面的空格,直到找到第一个非空格字符。

如果第一个字符不是数字字符或者负号,parseInt()就会返回NaN,如果第一个字符是数字字符则会继续解析直到遇到非数字字符位置。

var num1=parseInt("1234blue");//1234

var num2=parseInt("");//NaN

var num3=parseInt("0xA");//10(十六进制数)

var num4=parseInt("22.5");//22

var num5=parseInt("070");//56(八进制数)

var num6=parseInt("70");//70(十进制数)

var num7=parseInt("0xf");//15(十六进制数)

尽管parseInt()函数能够识别出各种整数格式,但是ECMAScript3和5在处理八进制数时存在分歧。

在ECMAScript3中"070"被当成八进制字面量,而在ECMAScript5已经不具备解析八进制数值的能力,因而会忽略前导0而将其直接转换为十进制数值。

为了消除在使用parseInt()函数时可能导致的困惑,可以为其提供第二个参数:转换时使用的基数(即多少进制),来保证得到正确的结果。

parseFloat()函数时从第一个字符开始解析直到遇到一个无效的浮点数字字符为止,也就是说字符串中的第一个小数点有效但第二个小数点就无效了。

parseFloat()函数始终都会忽略前导0,它可以识别浮点数值格式和十进制整数格式,但十六进制格式的字符串始终会被转换为0。

parseFloat()函数只解析十进制数值,因此它没有用第二个参数指定基数的用法,如果字符串包含的是一个可以解析为整数的值也会返回整数。

var num1=parseFloat("1234blue");//1234(整数)

var num2=parseFloat("0xA");//0(无法解析十六进制数,所有十六进制数均会被解析为0)

var num3=parseFloat("22.5");//22.5

var num4=parseFloat("22.34.5");//22.34(第二个小数点无效)

var num5=parseFloat("0908.5");//908.5(始终忽略前导0)

var num6=parseFloat("3.125e7");//31250000(科学计数法)

String类型用于表示由零个或多个16位Unicode字符组成的字符序列,即字符串。

字符串可以由单引号或双引号表示,在PHP中单引号和双引号会影响对字符串的解释方式不同,在ECMAScript中没有什么区别,但是要注意左右引号必须匹配。

String数据类型包含一些特殊的字符字面量,也叫转义序列,用于表示非打印字符,或者具有其他用途的字符。

\n 换行  \t 制表  \b 空格  \r 回车  \f 进纸  \\ 斜杠  \‘ 单引号  \" 双引号

\xnn 以十六进制代码nn表示的一个字符(其中n为0-F),例如:\x41表示"A"

\unnnn 以十六进制代码nnnn表示的一个Unicode字符(其中n为0-F),例如:\u03a3表示希腊字符∑

这些字符字面量可以出现在字符串中的任意位置,而且也将被作为一个字符来解析。

任何字符串的长度都可以通过访问其length属性取得,这个属性返回的字符数包括16位字符的数目,如果字符串中包含双字节字符,那么length属性可能不会精确地返回字符串中的字符数目。

ECMAScript中的字符串时不可变的,也就是说,字符串一旦创建,它们的值就不能改变。

要改变某个变量保存的字符串,首先要销毁原来的字符串,然后再用另一个包含新值的字符串填充该变量。

这个过程是在后台发生的,而这也是某些旧版本的浏览器中拼接字符串时速度很慢的原因,不过他们的高版本已经解决了这个问题。

要把一个值转换为字符串有两种方式:toString()方法和String()函数。

数值、布尔值、对象和字符串值都有toString()方法,而null和undefined没有这个方法。

多数情况下调用toString()方法不必传递参数,但是也可以传递输出数值的基数作为参数,这个参数可以是任意有效的进制格式,默认没有参数的输出值与指定基数10时的输出值相同。

在不知道要转换的值是不是null或undefined的情况下,可以使用String()函数,这个函数能够将任何类型的值转换为字符串。

如果该值有toString()方法,则调用该方法(没有参数)并返回相应结果;如果该值为null,则返回"null";如果该值是undefined,则返回"undefined"。

要把某个值转换为字符串,可以使用加好操作符把它与一个字符串("")加在一起。

ECMAScript中的对象其实就是一组数据和功能的集合。

对象可以通过执行new操作符后跟要创建的对象类型的名称来创建,例如:var o=new Object();

创建Object类型的实例并为其添加属性和方法,就可以创建自定义对象。

在ECMAScript中如果不给构造函数传递参数,则可以省略后面的那一对圆括号,但是并不推荐这么做。

在ECMAScript中Object类型是所有它的实例的基础,Object类型所具有的任何属性和方法也同样存在于更具体的对象当中:

constructor:保存着用于创建当前对象的函数,对于上面的例子而言就是构造函数Object();

hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中是否存在,其中作为参数的属性名(propertyName)必须以字符串的形式指定;

isPrototypeOf(Object):用于检查传入的对象是否是传入对象的原型;

propertyIsEnumerable(propertyName):用于检查给定的属性是否能够使用for-in语句来枚举,其中作为参数的属性名(propertyName)必须以字符串的形式指定;

toLocaleString():返回对象的字符串表示,该字符串与执行环境的地区对应;

toString():返回对象的字符串表示;

valueOf():返回对象的字符串、数值或布尔值表示,通常与toString()方法的返回值相同。

就技术的角度而言,ECMA-262对象的行为不一定适用于JavaScript中的其他对象。

浏览器环境中的对象,比如BOM和DOM中的对象都属于宿主对象,因为他们是由宿主实现提供和定义的。

ECMA-262不负责定义宿主对象,因此宿主对象可能会也可能不会继承Object。

JS基础知识回顾:ECMAScript的语法(二)

时间: 2024-12-28 04:12:09

JS基础知识回顾:ECMAScript的语法(二)的相关文章

JS基础知识回顾:引用类型(二)

ECMAScript中的Date类型是在早期Java中的java.util.Date类基础上构建的. 因此,Date类型使用自UTC(Coordinated Universal Time,国际协调时间)1970年1月1日午夜零点开始经过的毫秒数来保存日期. 在使用这种数据存储格式的条件下,Date类型保存的日期能够精确到1970年1月1日或之后的285616年. 要创建一个日期对象,使用new操作符和Date构造函数即可:var now=new Date(); 在调用Date构造函数而不传递参数

JS基础知识回顾:ECMAScript的语法(三)

ECMA-262描述了一组用于操作数据值的操作符,包括算术操作符.位操作符.关系操作符和相等操作符. ECMAScript操作符的与众不同之处在于,他们能够适用于很多值,例如字符串.数字值.布尔值.甚至是对象. 在将这些操作符应用于对象时,相应的操作符通常都会调用对象的valueOf()和(或)toString()方法,以便取得可以操作的值. 只能操作一个值的操作符叫做一元操作符. 递增和递减操作符直接借鉴自C,各有前置型和后置型两个版本:a++.++a.a--.--a 这四种操作符不仅适用于整

JS基础知识回顾:ECMAScript的语法(一)

任何语言的核心都必然会描述这门语言最基本的工作原理,而描述的内容通常都要涉及这门语言的语法.操作符.数据类型.内置功能等用于构建复杂解决方案的基本概念. ECMAScript中的一切变量.函数名.操作符都区分大小写. ECMAScript的标识符要符合下列规则:第一个字符必须是字母.下划线或美元符号:其他字符可以是字母.下划线.美元符号或数字. 标识符中的字母也可以包含扩展的ASCII或Unicode字母字符,但是并不推荐. 按照惯例,ECMAScript标识符采用驼峰大小写的格式来书写,尽管没

JS基础知识回顾:引用类型(一)

在ECMAScript中引用类型是一种数据结构,用于将数据和功能组织在一起,而对象时引用类型的一个实例. 尽管ECMAScript从技术上讲是一门面向对象的语言,但它不具备传统的面向对象语言所支持的类和接口等基本结构,所以虽然说引用类型与类看起来想死,但他们并不是相同的概念. 不过引用类型有的时候也可以被称为对象定义,因为他们描述的是一类对象所具有的属性和方法. 新对象是使用new操作符后跟一个构造函数来实现的,构造函数本身就是一个函数,只不过该函数时处于创建新对象的目的而定义的. ECMASc

JS基础知识回顾:引用类型(四)

每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法. 由于函数是对象,因此函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定. 函数的声明有以下三种形式: function sum(num1,num2){return num1+num2;}//利用函数声明语法定义 var sum=function(num1,num2){return num1+num2;}//利用函数表达式定义 var sum=new Function("num1","nu

JS基础知识回顾:引用类型(三)

ECMAScript通过RegExp类型来支持正则表达式. 使用类似Perl的语法就可以创建一个正则表达式:var expression=/pattern/flags; 其中模式(pattern)部分可以是任何简单或复杂的正则表达式,可以包含字符类.限定符.分组.向前查找以及反向引用. 每个正则表达式都可以带有一个或多个标志(flags),用以标注正则表达式的行为. 正则表达式的匹配模式只是下列三个标志: g:表示全局(global)模式,即模式将被应用于所有字符串,而非在发现第一个匹配项时立即

JS基础知识回顾:在HTML中使用JavaScript

想HTML页面中插入JavaScript的主要方法就是使用<script>元素. HTML4.01当中为<script>元素定义了下列6个属性: language(已废弃):原来用于表示编写代码使用的脚本语言,如JavaScript.JavaScript1.2.VBScript等,由于大多数浏览器会忽略此属性,因此就没有必要再用了: type(可选):可以看成是language的替代属性,表示编写代码使用的脚本语言的内容类型,也被称作MIME类型,在未指定此属性的情况下会被默认为t

JS基础知识回顾:变量、作用域和内存问题

ECMAScript变量可能包含两种不同数据类型的值:基本类型值和引用类型值. 基本类型值指的是简单的数据段,而引用类型值指的是那些可能由多个值构成的对象. 引用类型的值是保存在内存中的对象,与其他语言不同,JavaScript不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间. 在操作对象时,实际上是在操作对象的引用而不是实际的对象. 在很多语言中,字符串以对象的形式来表示,因此被认为是引用类型的,ECMAScript放弃了这一传统. 定义基本类型值和引用类型值的方式是类似的:创建

JS基础知识回顾:引用类型(六)

ECMA-262对内置对象的定义是:由ECMAScript实现提供的.不依赖于宿主环境的对象,这些对象在ECMAScript程序执行之前就已经存在了. 开发人员不必显式的实例化内置对象,因为他们已经实例化了. 前面我们已经介绍了大多数内置对象,如Object.Array.String,ECMA-262还定义了两个单体内置对象:Global和Math. Global对象可以说是ECMAScript中最特别的一个对象了,因为不管你从什么角度上看,这个对象都是不存在的. 实际上并没有全局变量或全局属性