#JavaScript学习#第五章:引用类型

260 阅读19分钟

Tips: 内容为知识梳理


目录

  1. Object 类型

  2. Array类型

  3. Date类型

  4. RegExp类型

  5. Function 类型

  6. 基本包装类型

  7. 单体内置对象


1. Object 类型

大多数引用类型都是Object类型的实例,创建Object类型实例方式有两种:

  1. 使用new后面跟Object构造函数

var obj1 = new object()

  1. 用对象字面量表示法,目的在于简化创建含有大量属性的对象的过程
var obj1= {
name:"object1";
age: 29; 
}

注意:

  • 属性后面跟冒号而不是等于号
  • 花括号内容可省略,即var obj={},这样做等价于var obj = new object{}

访问对象属性有两种方法:

  1. 点表示法

person.name

  1. 方括号表示法

person["name"],方括号表示法可通过变量来访问属性 即var word="name"; person[word];,也一样可以访问person的name属性


2. Array 类型

ECMAScript的数组每一项可以保存任意类型的数据,不需要每一项都相同。大小也可以动态调整。

  • 有两种方式创建数组:
  1. 用Array构造函数

var color = new array();

var color = new array(20);,长度为20的数组

var color = new array("red","blue","green");

var color = array(20);,省略new 结果相同

  1. 数组字面量表示法

var color =["red","blue","green"];

  • 数组从0开始,即color[0]为第一项。
  • 若数组只有3项,color[0],color[1],color[2],此时如果写如下代码:

color[3]="yellow";

数组自动增加一个长度。

  • 数组的length属性可设置,假如数组只有两项,此时设置color.length=3,则会自动新增一项,如果数组有三项,设置color.length=2,则会自动删除多出来的项。也可以使用color.length="black";自动往数组末尾新增一项

2.1 检测数组

用Array.isArray()方法检测某个值是不是数组

2.2 转换方法

  • 数组具有tolocaleString(),toString(),valueOf方法,后两个方法与其他对象的相同,而当数组调用tolocaleString()方法时,实际上是调用数组每一项的tolocaleString()方法,而不是toString()方法,虽然结果可能都是一样的。
  • 数组继承的 toLocaleString()、toString()和valueOf()方法默认情况下将数组的每一项以逗号分隔开返回

alert(color.toString());//red,blue,green

但可以使用join()方法改变分隔符

alert(color.join("||"));//red||blue||green

2.3 栈方法

为了实现类似栈的行为(后进先出),ECMAScript为数组提供了push()和pop()方法

  • color.push("red","green"),此方法将参数逐个添加到数组末尾,并放回修改后数组的长度
  • color.pop(),此方法用来移除数组最后一项,并放回被移除项的值

2.4 队列方法

队列方法与栈方法相反,遵循先进先出原则,有shift(),和unshift()方法

  • color.shift(),此方法可移除数组第一项并放回该项的值
  • color.unshift("red","green");,此方法用于在数组前端添加项,并返回数组长度

2.5 重排序方法

  • var value= [1,2,3,4,5]; value.reverse(); alert(value);输出5,4,3,2,1,reverse()方法可反转数组项顺序
  • sort()方法会调用每个数组项的toString方法,比较得到的字符串,再决定如何排序,使用sort()方法时可传入一个比较函数来作为参数,这个比较函数有两个参数,如果第一个参数应该位于第二个参数前则返回负数,如果两个参数相等则返回0,如果第一个参数应该位于第二个参数后则返回一个正数,这个比较函数的内容可按照自己需求来设定,下面是一个比较函数
function  compare(value1,value2){
if(value1<value2){return -1;}
else if(value1>value2){return 1;}
else{return 0;}
}

接着再将其传给sort:value.sort(compare),这样sort就会按照你写的比较函数来给数组的数排序,上面给的函数就是把小的排在前面

2.6 操作方法

  • concat()方法可基于当前数组创建一个新数组,将接受到的参数放在新数组末尾,即先复制当前数组到新数组,再将传入参数加到新数组末尾 如:
    var color1=["red","green"];
	var color2=color1.concat("yellow",["black","brown"])

这样color2的值就是red,green,yellow,black,brown

  • slice()方法可以选择数组的一个范围的项进行复制,可传入一个或两个参数,即开始项和结束项,若传入一个参数则这个参数指的是开始项的位置即第几项,并从这一项开始复制到最后一项,若传入两个参数,则结束项即第二个参数所指项不会被包含进复制内容:color.slice(1,4),这段代码表示从第2项复制到第4项,不会包括第五项(因为数组从0开始,所以1指的是第二项,4指的是第五项)
  • splice()方法

splice(第一项位置,删除数量,插入项值1,插入项值2) 可用于实现删除,替换,插入,返回被删除的项组成的数组,如:

   var color=["red","yellow"];
    remove= color.splice(0,1,"green");

这样做,color值就变为green和yellow,remove为red,其中splice的插入项可不要,无插入项即只做删除操作

2.7 位置方法

用indexof()和lastindexof()方法来查找项的位置,传入两个参数:要查找的项和表示查找起点位置的索引(可选) ,lastindexof表示从末尾开始查找,两个方法使用全等符号进行比较,返回项的位置,若找不到则返回-1。

2.8 迭代方法

ECMAScript为数组提供了五个迭代方法,五个方法都有两个传入参数:要运行的函数和运行该函数的作用域对象(可选),而要运行的函数包含三个传入参数:数组项的值,该项的位置,数组对象本身

  • every(),对数组每一项运行给定函数,若每一项运行函数都返回true,则返回true
  • filter(),对每一项运行给定函数,返回运行函数会返回true的项所组成的数组
  • foreach(),运行函数,无返回值
  • map(),运行函数,返回由函数返回结果所组成的数组
  • some(),运行函数,若有其中一项返回true则返回true

2.9 归并方法

用reduce()和reduceRight()迭代数组所有项,后者是从数组末尾开始遍历,两个方法都接受两个参数:每一项运行的函数和作为归并基础的初始值(可选)。而这个函数就受四个参数:前一个值,当前值,项的索引,数组对象。前一个值表示的是前一项运行完函数返回的值如果没运行则直接拿前一项的值作为第一个参数,当前值即当前项的值,如:

    var values=[1,2,3,4,5];
	var sum=values.reduce(function(prev,cur,index,array){
		return prev+cur;
	});
	alert(sum);//15

上面函数即对数组进行求和


3. Date类型

  • 创建一个日期对象有四种方法
  1. var obj=new Date("May 25,2004");,这里传入的参数会调用后台的date.parse方法
  2. var obj=new Date(2004 4 25 5 55 55),这里传入的参数会调用date.UTC方法
  3. var obj=new Date(date.parse("May 25,2004")),参数格式如下
  • 月/日/年
  • 英文月名 日,年
  • 英文星期几 英文月名 日 年 时:分:秒 时区
  1. var obj=new Date(date.UTC(2004 4 25 5 55 55),格式为年 月 日 小时 分钟 秒,月份从0开始,即0表示1月。参数中只有年和月是必须的,其他都可以省略,省略后为1日0:00:00。
  • Data.now()方法用于返回当前的时间的毫秒数
  • Date类型重写了tolocaleString()和toString()方法,使其以一定的格式放回时间,valueOf()方法则返回毫秒数

4. RegExp类型

  • 创建正则表达式:var expression = /pattren/ flags

flags有三个可取值:

  • g:全局模式,应用于所有字符串而非发现第一个匹配项就停止
  • i:不区分大小写模式
  • m:多行模式,到一行文本末尾时继续寻找下一行
  • 正则表达式的元字符必须转义,转义使用\即可,元字符有: ( [ { \ ^ $ | ) ? * + . ] }
  • 可用RegExp构造函数创建正则表达式,如: var obj = new RegExp("abc","i") 参数传的是字符串,前者为pattern后者为flags 所有元字符在这要进行双重转义即使用两个\进行转义

4.1 RegExp实例属性

每个实例都有如下属性:

  • global:布尔值,表示是否设置g标志
  • ignoreCase:布尔值,表示是否设置了 i 标志
  • lastIndex:整数,表示开始搜索下一个匹配项的字符位置,从 0算起
  • multiline:布尔值,表示是否设置了 m 标志
  • source:正则表达式的字符串表示,按照字面量形式而非传入构造函数中的字符串模式返回

4.2 RegExp实例方法

  • exec()方法用于捕获组,接受一个参数,即要搜索的字符串,返回包含第一个匹配项信息的数组
  • 数组包含两个额外属性,index和input,index表示匹配项在字符串的位置,input表示应用正则表达式的字符串
  • 数组的其他项则是与捕获组相匹配的字符串
  • 在设置全局标志情况下,exec会继续查找匹配项,而没有设置的话始终返回第一项
  • test()方法接受一个字符串参数,若该模式与参数匹配则返回true

4.3 RegExp构造函数属性

下面列出构造函数的属性


5. Function类型

声明函数:

  1. var sum =function(num1,num2){ return num1+num2; };
  2. function(num1,num2){ return num1+num2; } 函数名是指向函数对象的指针,一个函数可以有多个函数名

5.1 没有重载

函数名是指针,前面指向一个函数,后面又重新指向另一个函数,所以不会有重载这个东西。

5.2 函数声明与函数表达式

解析器会先读取函数声明,即

function sum(num1,num2){
	return num1+num2;
}

无论他在你的代码的什么位置,都会先把它添加到执行环境里面,这样就算有代码在这个函数声明之前引用这个函数,也不会报错 而函数表达式,即

var sum=function(num1,num2){...};

必须要等解析器运行到这里才会存在这个函数,在这个函数代码出现之前调用都是会出问题的

5.3 作为值的函数

函数名本身就是一个值,所以可以把函数作为一个值传递参数,也可以将一个函数作为另一个函数的结果返回

5.4 函数内部属性

函数内部有两个特殊的对象arguments和this

  • arguments用于保存函数参数,这个对象还有一个属性callee,该属性是一个指针,指向拥有这个arguments对象的函数
  • this与java中的大致类似,this引用的是函数当前的环境对象
  • caller保存着调用当前函数的函数的引用
function outer(){
   inner();
}	
function inner(){
   alert(inner.caller);
}
outer();

这里的inner.caller则指向outer(),因为outer()调用了inner()

5.5 函数的属性和方法

函数是对象也有自己的属性和方法,有两个属性:

  1. length:表示函数希望接受参数的个数
  2. prototype:保存函数所有的实例方法,下一章会详细介绍

每个函数包含两个非继承来的方法,都是在特定作用域中调用函数:

  1. apply():接受两个参数,一个是在其中运行的函数的作用域对象,另一个是参数数组,其中第二个可以是array实例也可以是arguments对象,如
function sum(num1,num2){
   return num1+num2;
}
function callsum(num1,num2){
   return sum.apply(this,arguments);
}
alert(callsum(10,10));

上面代码的this指向全局环境的window对象,因为callsum是在全局环境中运行的,而arguments数组则包含两个参数,num1和num2,因此最后会输出20

  1. call():与apply()作用相同,只是接受参数方式不同,第一个this不变,而后面的参数数组则要变为一个个参数,必须要把传入的参数列出来,如下:

sum.call(this,num1,num2);

两种方法都可以用来扩展作用域。

ECMAScript5还定义了一个方法: bind():这个方法会创建当前函数的一个实例,传入的参数会绑定到当前函数的this值。

   window.color="red";
    var o={color:"blue"};
    function sayColor(){
    alert(this.color);
    }  
    var obj=sayColor.bind(o);
   obj();

上面代码会输出blue,传入的o绑定到了obj的this里面,所以this.color就是blue

函数的toLocaleString和toString和valueOf方法始终返回函数的代码


6. 基本包装类型

Boolean,Number和String在被读取时,后台会自动创建一个对应的基本包装类型的对象。

	var s1="some word";
	var s2=s1.substring(2);

上面代码中s1是基本类型值String,s2调用了s1的substring方法,但逻辑上讲基本类型值不应该有方法,其实,在调用时,后台自动创建了String类型的一个实例,然后这个实例再调用substring方法,最后这个实例被销毁,可用如下代码实现:

    var s1 =new String("some word");
	var s2 =s1.substring(2);
	s1=null;

这样做,基本类型值就变得跟对象一样了,引用类型和基本包装类型的主要区别就是对象的生存期,引用类型在执行流离开作用域前都一直保存在内存中,而基本包装类型只在调用时存在,然后立即销毁,因此我们不能给基本类型添加属性和方法

Object构造函数会根据传入的值来返回相应的基本包装类型实例,如传入字符串则创建String实例。

6.1 Boolean类型

  • Boolean类型是引用类型

var obj= new Boolean(true)

它重写了toString方法,返回字符串"true"或"false" valueOf方法,返回布尔值true或false

  • 它不是一个布尔值,千万注意
  • 官方建议永远不要使用Boolean对象

6.2 Number类型

与Boolean类型差不多,重写了toString和valueOf方法,在第三章介绍过这里不再多说。

  • toFixed():将数值按照小数位返回为字符串,如:
    var num=10;
    alert(num.toFixed(2));

会输出10.00,2表示显示2位小数,如果本来的数有多过2位小数,则进行舍入

  • toExponential():返回以指数表示法(就是用e表示指数)表示数值的字符串形式,接受参数,参数表示小数位数
  • toPrecision():返回以固定位数表示的字符串,即传入一个参数,确定这个数要有多少位数,如:
   var num=99;
   num.toPrecision(1)//1e+2
   num.toPrecision(2)//99
   num.toPrecision(3)//99.0

第一个是100,因为没有任何1位数能精确表示99,所以就舍入为100

  • 官方不建议直接实例化Number类型

6.3 String类型

String类型的length属性表示字符串中含有多少个字符 String类型也有很多方法:

  1. 字符方法

    charAt()和charCodeAt(),接受参数为要访问特定字符的位置,从0开始算起,charAt()返回这个位置的字符,charCodeAt()返回这个位置字符的字符编码,也可以用方括号加字符位置来实现charAt()的功能 var stl="word" stl[1] 输出"o"

  2. 字符操作方法
  • concat():用于在原字符对象基础上创建新字符对象,并将传入参数拼接到原字符对象的末尾,它可以接受任意参数,按顺序拼接
  • slice():从原字符串中截取,传入两个参数,开始位置和结束位置,不包含结束位置的字符,若参数为负值则将其与字符总长度相加
  • substr():从原字符串中截取,两个参数,开始位置和要返回字符的个数,若为负值,第一个负的参数加上总长度,第二个负参数变为0 +substring():从原字符串中截取,传入两个参数,开始位置和结束位置,不包含结束位置的字符,若参数为负值则将其变为0
  1. 字符串位置方法

indexOf和lastIndexOf,搜索字符,传入两个参数,第一个是要搜索的字符,第二个参数可选,是指定从哪里开始搜索,返回字符所在位置

  1. trim()方法

用于创建一个基于原字符串的新字符串,新字符串中会删除原字符串的前置和后缀的空格

  1. 字符串大小写转换方法

用toLowerCase()、toLocaleLowerCase()、toUpperCase()和 toLocaleUpperCase()进行大小写转换,lower表示小写,upper表示大写

  1. 字符串的模式匹配方法
  • match()方法:本质上与RegExp的exec()方法相同,只接受一个参数,即正则表达式或RegExp对象,match()返回一个数组,数组的第一项是与整个模式匹配的字符串,之后的每 一项(如果有)保存着与正则表达式中的捕获组匹配的字符串
  • search()方法:与match()方法参数相同,返回字符串中第一个匹配项的位置,如果没有则返回-1。
  • replace()方法:用于替换指定字符,接受两个参数,第一个参数为RegExp对象或一个字符串,即要替换掉的内容,第二个参数为一个字符串或一个函数,即要换上的内容,若第一个参数是字符串则只会替换掉第一个符合条件的字符,可以改为正则表达式并设定为全局模式,这样就可以替换所有符合条件的字符。第二个参数可以是函数,函数有三个参数:模式的匹配项、模式匹配项在字符串中的位置和原始字符串,函数返会字符串即原来的第二个参数
  • split()方法:用于将字符串按照指定分隔符分隔,存入数组,接受两个参数,第一个参数是分隔符,可以是字符串,也可以是RegExp对象。第二个参数可选,是指定数组的大小的数,超过大小则不再存放多余的字符串。
  1. localeCompare()方法

用于比较两个字符串,即原字符串和传入的参数字符串。并返回下列值:

  • 如果字符串在字母表中应该排在字符串参数之前,则返回一个负数
  • 如果字符串等于字符串参数,则返回 0
  • 如果字符串在字母表中应该排在字符串参数之后,则返回一个正数
  1. fromCharCode()方法

这个方法用于接受一个或多个字符串编码,然后再转换成字符串,是String构造函数的一个静态方法,可直接使用,如下所示:

alert(String.fromCharCode(104, 101, 108, 108, 111)); //"hello"


7. 单体内置对象

内置对象定义为:由 ECMAScript实现提供的、不依赖于宿主环境的对象,这些对 象在 ECMAScript程序执行之前就已经存在了。意即开发人员不用实例化内置对象,其中Object、Array 和 String都是内置对象

7.1 Global对象

全局对象不属于任何其他对象的属性或方法,而在全局作用域中定义的属性和函数都是Global对象的属性。Global对象包含一些其他方法

  1. URI编码方法

Global 对象的 encodeURI()和 encodeURIComponent()方法可以对 URI进行编码,以便发送给浏览器 其中,

  • encodeURI()主要用于整个 URI(例如,www.wrox.com/illegal value.htm)
  • 而 encode- URIComponent()主要用于对 URI中的某一段(例如前面 URI中的 illegal value.htm)进行编码。
  • 它们的主要区别在于,encodeURI()不会对本身属于 URI 的特殊字符进行编码,例如冒号、正斜杠、 问号和井字号;而 encodeURIComponent()则会对它发现的任何非标准字符进行编码。encodeURI()编码后的结果是除了空格之外的其他字符都原封不动,只有空格被替换成了 %20;而 encodeURIComponent()方法则会使用对应的编码替换所有非字母数字字符

与 encodeURI()和 encodeURIComponent()方法对应的两个方法分别是 decodeURI()和 decodeURIComponent()

  • decodeURI()只能对使用 encodeURI()替换的字符进行解码
  • decodeURIComponent()能够解码使用 encodeURIComponent()编码的所有字符
  1. eval()方法

eval()方法就像一个完整的ECMAScript解析器,只接受一个参数,即要执行的ECMAScript代码

  • eval("alert("124")")等价于alert("124")
  • 被执行的代码具有与该执行环境相同的作用域链,即eval()中的代码可以使用在包含环境中定义的变量,而在eval()中写的函数,也可以被外部代码引用
  • eval()中创建的任何变量或函数都不会被提升,直到运行到eval这里才能被创建
  • 在严格模式下,外部不能访问eval创建的任何变量和代码,也不能对eval赋值
  1. Global 对象的属性

下表列出了Global对象的所有属性

4. window对象

其中一种取得Global对象的方法是使用window对象

  • 在全局作用域声明的所有变量和函数都成了window对象的属性

另一种取得Global对象的方法是使用如下代码:

    var global = function(){ 
	    return this; 
	     }(); 

简单的返回this来取得Global对象


7.2 Math对象

Math对象用于提供计算功能

  1. Math对象的属性 下表列出了Math对象包含的一些属性,其中大都是数学计算可能用到的特殊值

2. min()和 max()方法 min()和max()用于确定一组数值的最大值和最小值,都可以接受任意数量的参数 可以用如下代码找出数组的最大值

    var values = [1, 2, 3, 4, 5, 6, 7, 8]; 
	var max = Math.max.apply(Math, values); 
  1. 舍入方法
  • Math.ceil()执行向上舍入,即它总是将数值向上舍入为接近的整数
  • Math.floor()执行向下舍入,即它总是将数值向下舍入为接近的整数
  • Math.round()执行标准舍入,即它总是将数值四舍五入为接近的整数
  1. random()方法

用Math.random()返回0~1的一个随机小数,可套用一些数学公式来获得一个你想要范围的随机数。

  1. 其他方法

下表列出了Math对象包含的一些其他方法,与复杂计算有关的方法