《JavaScript高级程序设计》第5章 引用类型

5 引用类型

ECMAScript中,引用类型是一种数据结构,用于将数据和功能组织在一起。尽管ECMAScript从技术上讲是一门面向对象的语言,但它不具备传统的面向对象语言所支持的类和接口等基本结构。

ECMAScript提供了很多原生引用类型,以便开发人员用以实现常见的计算任务。


Object类型:

创建Object实例的方式有两种。第一种是使用new操作符后跟Object构造函数,例如var person = new Object();  第二种是使用对象字面量表示法。对象字面量是对象定义的一种简写形式,目的在于简化创建包含大量属性的对象的过程。var person = { name: aaa’,age:26};

一般来说,访问对象属性时使用的都是点表示法。不过,在JavaScript也可以使用方括号表示法来访问对象的属性。在使用方括号语法时,应该将要访问的属性以字符串的形式放在方括号中。这两种方式没有区别,但方括号语法的主要优点是可以通过变量来访问属性。


Array类型:

ECMAScript数组的每一项可以保存任何类型的数据。而且,ECMAScript数组的大小是可以动态调整的,即可以随着数据的增加自动增长以容纳新增数据。

创建数组的基本方式有两种:

1)使用Array构造函数,如var colors = new Array();如果预先知道数组要保存的项目数量,也可以给构造函数传递该数量,而该数量会自动变成length属性的值。也可以向Array构造函数传递数组中应该包含的项。另外,在使用Array构造函数时也可以省略new操作符。

2)使用数组字面量表示法,数组字面量由一对包含数组项的方括号表示。如var colors = [‘red’,’blue’];

检测数组:

Instanceof操作符的问题在于,它假设只有一个全局执行环境,但实际中可能存在两个不同的Array构造函数。为了解决这个问题,ECMAScript5新增了Array.isArray()方法。这个方法的目的是最终确定某个值到底是不是数组。使用方法如if(Array.isArray(value)){ }

转换方法:

所有对象都具有toLocaleString()、toString()和valueOf()方法。其中,调用数组的toString()方法会返回由数组中每个值的字符串形式拼接而成的一个以逗号分隔的字符串。

toLocaleString()方法经常也会返回与toString()和valueOf()方法相同的值,但也不总如此,当调用数组的toLocaleString()方法时,会调用每一项的toLocaleString()方法。

join()方法只接收一个参数,即用作分隔符的字符串,然后返回包含所有数组项的字符串。

如果数组中的某一项的值是null或者undefined,那么该值在join()、toLocaleString()、toString()和valueOf()方法返回的结果中以空字符串表示。

栈方法:

push()方法可以接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改后的数组长度。

pop()方法则从数组末尾移除最后一项,减少数组的length值,然后返回移除的项。

队列方法:

shift()方法能够移除数组中的第一个项并返回该项,同时将数组长度减1

ECMAScript还为数组提供一个unshift()方法,它能在数组前端添加任意个项并返回新数组的长度。

重排序方法:

数组中已经存在两个可以直接用来重排序的方法:reverse()和sort()。

默认情况下,为了实现排序,sort()方法会调用每个数组项的toString()转型方法,然后比较得到的字符串。即使数组中的每一项都是数值,sort()方法比较的也是字符串。不用说,这种排序方法在很多情况下都不是最佳方案,因此sort()方法可以接收一个比较函数作为参数,以便我们指定哪个值位于哪个值的前面。

比较函数接收两个参数,如果第一个参数应该位于第二个之前则返回一个负数,位于之后则返回一个正数,相等返回0

操作方法:

concat()方法先创建当前数组一个副本,然后将接收到的参数添加到这个副本的末尾,最后返回新构建的数组。

slice()方法它能够基于当前数组中的一个或多个项创建一个新数组,可以接受一个或两个参数,即要返回项的起始和结束位置。如果只有一个参数,则返回从该参数位置到结束的所有项。如果有两个参数,该方法返回起始和结束位置之间的项,但不包括结束位置的项。注意slice()方法不会影响原始数组。

splice()方法:始终都返回一个数组,该数组中包含从原始数组中删除的项(如果没有删除的项,则返回一个空数组)。

1)删除:可以删除任意数量的项,第一个参数是起始位置,第二个参数是项数;

2)插入:可以向指定位置插入任意数量的项,只需提供三个参数,起始位置、0(要删除的项数)、要插入的项;

3)替换:可以向指定位置插入任意数量的项,同时删除任意数量的项,只需三个参数:起始位置、要删除的项数、要插入的项;

位置方法:

ECMAScript 5为数组实例添加了两个位置方法:indexOf()和lastIndexOf()。这两个方法都接收两个参数,要查找的项和起点位置的索引。没有找到返回-1,使用全等进行比较。

迭代方法:

ECMAScript 5为数组定义了5个迭代方法。每个方法都接收两个参数:要在每一项上运行的函数和运行该函数的作用域对象。传入这些方法中的函数会接收三个参数:数组项的值、该项在数组中的位置和数组对象本身。

every():对数组中的每一项运行给定函数,如果该函数对每一项都返回true,则返回true

filter():对数组中的每一项运行给定函数,返回该函数会返回true的项组成的数组。

forEach():对数组中的每一项运行给定函数,这个方法没有返回值。

map():对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。

some():对数组中的每一项运行给定函数,如果该函数对任一项返回true,则返回true

归并方法:

ECMAScript 5还新增了两个归并数组的方法:reduce()和reduceRight()。这两个方法都会迭代数组的所有项,然后构建一个最终返回的值。这两个方法都接收两个参数:一个在每一项上调用的函数和作为归并基础的初始值。这个函数接收4个参数:前一个值、当前值、项的索引、数组对象。应用场景:求数组和。


Date类型:

ECMAScript中的Date类型是在早期Java中的java.util.Date类基础上构建的。

在调用Date构造函数不传递参数时即获得当前日期和时间,传递参数则需要毫秒数。为了简化计算毫秒数,ECMAScript提供了两个方法:Date.parse()和Date.UTC()。如new Date(Date.parse(“2/5/2018”));  

new Date(Date.UTC(2018,1,5,12,12,12));

Date.now();方法返回表示调用这个方法时的日期和时间的毫秒数。在不支持Date.now()方法的浏览器中使用+操作符+new Date();也可以达到同样的目的。

继承的方法:

与其他引用类型一样,Date类型也重写了toLocaleString()、toString()和valueOf()方法;Date类型的toLocaleString()方法会按照与浏览器设置的地区相适应的返回日期和时间;toString()方法则通常返回带有时区信息的日期和时间;valueOf()方法返回日期的毫秒数。

日期格式化方法:

toDateString—显示星期几、月、日、年;toTimeString—显示时、分、秒、时区;toLocaleTimeStringtoLocaleTimeStringtoUTCString

日期/时间组件方法:

getFullYear():取得4位数的年份;

getMonth():返回日期中的月份,其中0表示一月;

getDate():返回日期月份中的天数(131);

getDay():返回日期中星期的星期几(0表示星期日);

getHours():返回日期中的小时数(023);

getMinutes():返回日期中的分钟数(059);

getSeconds():返回日期中的秒数(059);

getMilliseconds():返回日期中的毫秒数;


RegExp类型:

var expression = /pattern/flags;

Flags可以是:g—表示全局模式,即模式将被应用于所有字符串,而非在发现第一个匹配项时立即停止;i—表示不区分大小写模式;m—表示多行模式;

1)匹配第一个“bat“或”cat”,不区分大小写    var pattern1 = /[bc]at/I;

2)匹配所有以“at”结尾的3个字符的组合,不区分大小写    var pattern2 = /.at/gi;

对元字符匹配要使用转义字符。

上面这两个例子是以字面量形式来定义的正则表达式。另一种创建正则表达式的方式是使用RegExp构造函数,它接收两个参数:一个是要匹配的字符串模式,另一个是可选的标志字符串。var pattern3 = new RegExp(“[bc]at”,”i”); pattern1相同。

由于RexExp构造函数的模式参数是字符串,所以在某些情况下要对字符串进行双重转义。

字面量模式/\[bc\]at/  ====   等价的字符串”\\[bc\\]at

使用正则表达式字面量和使用RegExp构造函数创建的正则表达式不一样,在ECMAScript 3中,正则表达式字面量始终会共享一个RegExp实例,而使用构造函数创建的每一个新RegExp实例都是一个新实例。

ECMAScript 5明确规定,使用正则表达式字面量必须像直接调用RegExp构造函数一样,每次都创建新的RegExp实例。

RegExp实例方法:

1RegExp对象的主要方法是exec(),该方法是专门为捕获组而设计的。exec()接受一个参数,即要应用的字符串,返回包含第一个匹配项信息的数组;或者没有匹配项的情况下返回null。在数组中,第一个项是与整个模式匹配的字符串,其他项是与模式中的捕获组匹配的字符串。

对于exec()方法而言,在不设置全局标志的情况下,多次调用exec()将始终返回第一个匹配项的信息。而在设置全局标志的情况下,每次调用exec()则都会在字符串中继续查找新匹配项。

2)正则表达式的第二个方法是test(),它接受一个字符串参数。在模式与该参数匹配的情况下返回true;否则返回false

RegExp实例继承的toLocaleXString()和toString()方法都会返回正则表达式的字面量,与创建正则表达式的方式无关。



Function类型

函数实际上都是对象,每个函数都是Function类型的实例。由于函数是对象,因此函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定。

函数声明和函数表达式定义函数。解析器会率先读取函数声明,并使其在执行任何代码之前可用。至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解释执行。

ECMAScript中没有函数重载的概念,因为函数名只是函数对象的指针,会进行覆盖。

在函数内部,有两个特殊的对象:argumentsthisthis引用的是函数据以执行的环境对象或者也可以说是this值(当在网页的全局作用域中调用函数时,this对象引用的就是window)。

ECMAScript 5也规范了另一个函数对象的属性:caller。这个属性中保存着调用当前函数的函数的引用。

每个函数都包含两个属性:lengthprototype。其中,length属性表示函数希望接收的命名参数的个数。prototype是保存它们所有实例方法的真正所在。在ECMAScript 5中,prototype属性是不可枚举的,因此用for-in无法实现。

每个函数都包含两个非继承而来的方法:apply()和call()。这两个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。首先apply()方法接收两个参数:一个是在其中运行函数的作用域,另一个是参数数组。其中第二个参数可以是Array实例,也可以是arguments对象。call()方法与apply()方法的作用相同,区别仅在于参数的变化,call传递给函数的参数必须逐个列出来。使用call()或apply()来扩充作用域的最大好处,就是对象不需要与方法有任何耦合关系。

ECMAScript 5还定义了一个方法:bind()。这个方法给函数创建一个实例,其this值会被绑定到传给bind()函数的值。


基本包装类型

实际上,每当读取一个基本类型值的时候,后台就会创建一个对应的基本包装类型的对象。

引用类型与基本包装类型的主要区别就是对象的生存期,使用new操作符创建的引用类型实例,在执行流离开当前作用域之前都一直保存在内存中,而自动创建的基本包装类型的对象,则只存在于一行代码的执行瞬间,然后立即被销毁。

Boolean类型:不建议使用,在使用typeof测试基本类型时返回boolean,测试引用类型时返回objectinstanceof测试基本类型时返回false,测试引用类型时返回true

Number类型:toFixed()方法传入数值几就表示显示几位小数。

String类型:

concat():连接字符串

slice()、substr()、substring()方法都接受一个或两个参数。第一个参数表示子字符串起始位置,第二个参数为结束位置,对substr()来说第二个参数是字符个数。

indexOf()、lastIndexOf()这两个方法都是从一个字符串中搜索给定字符串,然后返回子字符串的位置,没有找到则返回-1

trim():删除字符串前后空格。

字符串的模式匹配方法:match()、search()、replace()方法。

localeCompare():这个方法比较两个字符串。


单体内置对象

ECMAScript实现提供的、不依赖于宿主环境的对象,这些对象在ECMAScript程序执行之前就已经存在了。例如ObjectArrayStringGlobalMath

1Global对象:“兜底儿对象”,换句话说,不属于任何其他对象的属性和方法,最终都是它的属性和方法。

URI编码方法:encodeURI()和encodeURIComponent()可以对URI进行编码,以便发送给浏览器。encodeURI不会对本身属于URI的特殊字符进行编码,例如冒号、正斜杠、问好、井字号;而encodeURIComponent()则会对它发现的任何非标准字符进行编码。

Global对象还包含一些属性,例如,特殊的值undefinedNaN以及Infinity都是Global对象的属性,此外,所有原生引用类型的构造函数,像ObjectFunction,也都是Global对象的属性。

ECMAScript虽然没有指出如何直接访问Global对象,但Web浏览器都是将这个全局对象作为window对象的一部分加以实现的。


Math对象

Math.ceil()执行向上舍入,即它总是将数值向上舍入为最接近的整数。

Math.floor()执行向下舍入,即它总是将数值向下舍入为最接近的整数。

Math.round()执行标准舍入,即它总是将数值四舍五入为最接近的整数。

Math.random()方法返回大于等于0小于1的一个随机数。

从某个整数范围内随机选择一个值:

= Math.floor(Math.random()*可能值的总数 + 第一个可能的值)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值