JavaScript第五章
引用类型
引用类型是一种将数据和功能组织在一起的数据结构。
引用类型:描述的是一类对象所具有的属性和方法; 对象是某个特定引用类型的实例。
1.Object类型
创建Object实例的方法有两种:
(1) new操作符后跟Object构造函数
(2) 使用对象字面量表示法,向函数传递大量可选参数的首选方式;var person = {}
对象字面量表示法:
对象的属性名会自动转换为字符串;
在函数内部,可以使用typeof 操作符来检测每个属性是否存在;
函数传参技巧:对于必须值使用命名参数,使用对象字面量来封装多个可选参数
访问对象属性:①点表示法: person.name ②方括号表示法:person["name"]
(使用方括号时,要将访问的属性以字符串或者变量的形式放入方括号中)
2.Array类型
数组:每一项都能保存任何类型的数据,大小可以动态调整;
创建数组的方法:
- var color = new Array()new也可以省略;
- 字面量表示法:最后一项后面不要跟逗号
使用构造函数创建时,可以向构造函数传递数组中的包含项、数组的长度(数字);包含项有多个,用逗号隔开;如果传递了一个值,数字的话就是指定的长度,其他类型的参数则创建包含那个值的数值
读取和设置数组的值:使用方括号并提供索引,从0开始
如果将数组的length设置为大于项数的值,则新增的每一项都会取得undefined;
利用length属性可以方便的在数组末尾添加新项var co
= [1,2,3,3];co[co.length]=4;co[co.length]=5;
- 检测数组
Array.isArray()方法(ie9及以上),确定某个值到底是不是数组,而不管他是在哪个全局执行环境中创建的;instanceof对于单一的全局执行环境没问题,但是如果有多个全局执行环境,就会存在两个版本的Array构造函数。 - 转换方法
toString():返回由数组中每个值的字符串形式拼接而成的一个以逗号分隔的字符串
valueOf():返回的还是数组,
toLocaleString():数组中每一项调用toLoacleString,然后逗号拼接上,
默认情况下会以逗号分隔字符串的形式返回数组项,如果使用join()方法,则可以指定分隔符构建字符串(只有一个参数,分隔符的字符串,不传的话默认逗号分隔符)。若数组中的某一项为null或undefined,会返回空字符串
- 栈方法(后进先出方法)
push():可以接收任意数量参数,然后将其逐个添加到数组末尾,并返回修改后的数值长度;pop()方法从数组末尾移除最后一项,减少数组长度,并返回移除项 - 队列方法(先进先出)
shift()移除数组的第一项并返回该项,将数组长度减一;unshift()在数组前端添加任意个项,并返回新数组长度; - 重排序方法
reverse():反转数组项的顺序;但是不够灵活;如果只是想反转数组原来的顺序,使用这个较快;
sort():默认情况下按升序排列数组项(调用每个数组项的toString方法,得到字符串,然后确定如何排序,默认会造成数字5在10的后面,因为比较的是字符串);
sort 方法可以接收一个比较函数作为参数,比较函数接收两个参数,返回结果为正负零; - 操作方法(数值)
concat()方法:不会改变原数组,会返回一个新构建的数组;
slice()方法,基于当前数值的一个或多个项创建一个新数组,可以接收一或两个参数(项的起始和结束位置),只有一个的话结束位置为数组末尾,两个的话返回起始和结束位置的项,但不包括结束位置的项,不会影响原来的数值;如果有负数,则用数组长度加上该数确定相应位置,如果结束小于初始,则返回空数组
splice()方法,向数组中部插入项, - 删除任意数量的项,要删除的第一项的位置和要删除的项数
- 插入:向指定的位置插入任意项,需提供三个参数:起始位置、0(要删除的项数)和要插入的项,如果要插入多项,可以传入第四、第五以至任意多项
- 替换:参数为:起始位置,要删除的项数和要插入的任意项,插入的项数不必与删除的项数相等
splice 始终会返回一个数组,该数组中包含从原始数值中的删除项(如果删除为0,则返回空数组) - 位置方法
indexOf()、lastIndexOf()方法,接收两个参数:要查找的项与(可选的)查找的起始位置;
indexOf(从0向后查找);
lastIndexOf(从数值末尾开始向前查找)
返回查找的项在数组中的位置,没有的情况下返回-1;在比较是否相等是用的全等操作符(两个对象,即使字段名、值都一样,全等时也不相等) - 迭代方法
5个迭代方法。每个方法都接收两个参数:要在每一项上运行的函数和(可选的)运行该函数的作用域对象——影响this的值;传入这些方法的函数会接收三个参数:数组项的值,该项在数组中的位置和数组对象本身。 - every 对数组中都每一项运行给定函数,如果每一项都返回true,则返回true
- filter() 对数组中的每一项运行给定函数,返回该函数会返回true的项组成的数组
- forEach()对数组的每一项运行给定函数。没返回值
- map() 对数组的每一项运行给定函数。返回每次函数调用的结果组成的数组
- some() 对数组的每一项运行给定函数。如果该函数对任一项返回true,则返回true
以上方法都不会修改函数中的包含值 - 缩小方法
reduce()、reduceRight(),这两个方法都会迭代数值的所有项,然后构建一个最终返回的值
reduce 从第一项开始,逐个遍历到最后
reduceRight 从最后一项开始,向前遍历
接收参数为:一个每项调用的函数和(可选的)作为缩小基础的初始值
传给reduce和reduceRight 的函数接收4个参数:前一个值、当前值、项的索引和数组对象。这个函数返回的任何值都会作为第一个参数自动传给下一项
3. date类型
创建date对象:构造函数 new Date()
可以根据特定的日期和时间创建日期对象,必须传入该日期的毫秒数,可以通过Date.parse()和Date.UTC(),日期对象在不同浏览器中表现不同,如果1 32,2007有的会解析成2 1,2007,但是有的会解析成当前时间
- 其中parse()方法接收一个表示日期的字符串参数,然后尝试根据这个字符串返回相应的日期的毫秒数。若传入的字符串不能表示日期,则会返回NaN。实际上如果直接传入字符串给new Date(),也会在后台调用Date.parse();
- Date.UTC() 也会返回表示日期的毫秒数,入参为
年份、月份(0-11)、天数(1-31)、小时(0-23)、分钟、秒、毫秒。其中只有年月是必须的,没有天数则为1,其他没有则为0;
Date()构造函数与Date.UTC()接收参数相同
Date.now()方法,返回调用这个方法时的日期和时间的毫秒,在不支持它的浏览器中,使用+操作符将ate对象转换成字符串,也是一样的效果 - 继承的方法
与其他引用类型一样,Date类型也重写了toLocaleString(),toString()和valueOf()方法,其中valueOf 返回毫秒数,其他两个返回字符串;Date类型可以使用比较操作符比较(会使用valueOf 转化为毫秒数) - 日期格式化方法
toDateString()—— 以特定于实现的格式显示星期几、月、日和年
toTimeString()—— 以特定于实现的格式显示时、分、秒和时区
toLocaleDateString()—— 以特定于地区的格式显示星期几、月、日和年
toUTCString()—— 以特定于实现的格式完整的utc日期 - 日期、事件组件方法
- RegExp类型
每个正则表达式都可带有一个或多个标志(flags),用于表明正则表达式的行为;有以下三个标志:g(全局模式,被应用与所有字符串);i(不区分大小写);m(多行模式,到达一行末尾还会继续查找下一行
正则表达式就是一个模式与上述标志的组合体;
正则表达式的元字符包括 ( | { \ ^ $ | ? * + . [ ] }
模式中使用的元字符必须转义(即要匹配元字符,用\ )
定义正则表达式
- 字面量形式:var pattern = /[bc]at/i
- 使用RegExp构造函数,接收两个参数,一个是要匹配的字符串模式,另一个是可选的标志字符串。var pattern1 = new RegExp("[bc]at","i");在构造函数中要对字符进行双重转义
ECMAScript 3 中,每个正则表达式字面量始终会共享一个RegExp实例,而使用构造函数创建的每一个新RegExp实例都是新实例;对于字面量,第一册调用test会找到cat,第二次会从上一次匹配的末尾开始,之后由于到了字符串末尾,下次调用test就又从开头开始了。
- var re = null,
- i;
- for (i = 0; i < 10;i++){
- re = /cat/g;
- re.test("catastrophe");
- }
- for (i = 0; i < 10; i++){
- re = new RegExp("cat","g");
- re.test("catastrophe");
}
ECMAScript 5明确规定,字面量和构造函数一样,每次都新建RegExp实例
RegExp实例属性
RegExp实例局域下列属性
- global 布尔值,是否设置了g标志
- ignoreCase 布尔值,是否设置了g标志
- multiline 布尔值,是否设置了m标志
- lastIndex 整数,表示开始搜索下一个匹配项的字符位置,从0算起
- source 正则表达式的字符串表示,按照字面量形式而非传入构造函数中的字符串模式返回
RegExp 实例方法
exec(),该方法是专门为捕获组而设计的;
exec()接受一个参数,即要应用模式的字符串,然后返回包含第一个匹配项信息的数组;没匹配时返回null
返回的数值时Array实例,还包括两个额外的属性,index(匹配项在字符串的位置)和input(应用正则表达式的字符串)。数组中的第一项与整个模式匹配的字符串,其他项是与模式中的捕获组匹配的字符串(如果模式中没有捕获组,则该数组只包含一项)
var text = "mom and dad and baby";
var pattern = /mom (and dad (and baby)?)?/gi;
var matches = pattern.exec(text);
alert(matches.index);
alert(matches.input);
alert(matches[0]);
alert(matches[1]);
alert(matches[2]);
不设置全局标志的情况下,在同一个字符串上多次调用exec()将始终返回第一个匹配项的信息,而在设置全局标志的情况下,每次调用exec()都会在字符串张继续查找新匹配项
test()方法,只接受一个字符串参数,在模式与参数匹配的情况下返回true,否则返回false。常放在if语句中
RegExp实例继承的toLocalString,toString
方法都会返回正则表达式的字面量,与创建正则表达式的方式无关
valueOf 返回正则表达式本身
RegExp构造函数属性
这些属性适用于作用域中的所有正则表达式,并且基于所执行的最近一次正则表达式操作而变化,可以通过长属性名和短属性名来访问
长属性名 |
短属性名 |
说明 |
input |
$_ |
最后一次匹配的字符串 |
lastMatch |
$& |
最后一次匹配项 |
lastParen |
$+ |
最后一次匹配的捕获组 |
leftContext |
$` |
input字符串中的lastMatch之前的文本 |
multiline |
$* |
布尔值,是否所有表达式都使用多行模式 |
rightContext |
$’ |
input字符串中的lastMatch之后的文本 |
RegExp.$1-9,用于存储第一、第二到第九匹配的捕获组,在执行exec()或test()方法时,这些属性自动填充
Function类型
每个函数都是Function类型的实例,与其他引用类型一样具有属性和方法(函数是对象,函数名实际是一个指向函数对象的指针,而不是绑定)。访问函数的指针而不执行函数的话,必须去掉函数名后面的圆括号
function sum(){}
或
var sum = function(){};
或
var sum = new Function ()//不推荐
没有重载
因为函数名只是指针,声明两个同名函数,后面的函数覆盖了前面的函数(第二个变量覆盖了第一个变量)
函数声明和函数表达式
函数声明:解析器率先读取函数声明,使其在执行任何代码之前可用,至于函数表达式,必须等到解析器执行到它所在的代码行,才会真正被解释执行
上面不会报错,而下面的写法会报错,因为执行到函数所在语句之前,变量sum中不会保存有对函数的引用
sum (10,10);
function(num1,num2){
return num1+num2;
}
或
var sum = function(num1,num2){
return num1+num2;
}
作为值的函数
函数名本身就是变量,所以函数也可以作为值来使用,不仅可以像传递参数一样把一个函数传递给另一个函数,而且可以将一个函数作为另一个函数的结果返回
用于给sort函数传入比较函数(比较规则,默认为toString方法确认顺序)
函数内部属性
arguments 和this 这两个对象
- 其中arguments主要是用来保存函数参数,但这个对象还有一个callee的属性,该属性有一个指针,指向拥有这个arguments对象的函数;即arguments.callee() 指向原函数
- this–引用的是函数据以执行的环境对象(当在网页的全局作用域中调用函数时,this对象引用的就是window)
window.color = "red";
var o = {color:"blue"};
function sayColor(){
console.log(this.color);
}
sayColor();//"red"
o.sayColor = sayColor;
o.sayColor();
ECMAScript 5规范了另一个函数对象的属性:caller(调用当前函数的函数的引用,如果是在全局作用域中调用当前函数,值为null)
当在严格模式下时,arguments.callee会导致错误,arguments.caller也会报错,与函数的caller不同,严格模式下也不能为函数的caller属性赋值
函数的属性和方法
每个函数都包含length(函数希望接收的命名参数的个数)和prototype(保存它们所有实例方法的真正所在),
在ECMAScript 5中,prototype属性不可枚举,for-in无法发现
每个函数都包含两个非继承而来的方法,apply()和call()
这两个方法都是在特定作用域中调用的函数,实际上等于设置函数体内this对象的值;
- apply()方法接收两个参数:一个在其中运行函数的作用域,另一个是参数数组(可以使数组或arguments对象)
- call()方法与apply方法作用相同,区别仅在于接收参数的方式不同,第一个参数是this,其余参数直接传递给函数
- 这两个函数强大的地方是能够扩充函数赖以运行的作用域
window.color = "red";
var o = {color:"blue"};
function sayColor(){
console.log(this.color);
}
sayColor();//"red"
sayColor.call(this);//"red"
sayColor.call(window);//"red"
sayColor.call(o);//"blue"
使用这两个方法来扩展作用域的最大好处,就是对象不需要与方法有任何耦合关系
- ECMAScript 5还定义了一个方法,bind(),这个方法会创建一个函数实例,其中this会被绑定到传给bind()函数的值
window.color = "red";
var o = {color:"blue"};
function sayColor(){
console.log(this.color);
}
var objectSayColor = sayColor.bind(o);
objectSayColor();//blue
- toLocaleString 和toString 和valueOf方法始终都返回函数的代码
基本包装类型
3个特殊的引用类型Boolean、Number和String(每当读取一个基本数据类型的时候,后台就会创建一个对应的基本包装类型的对象,从而可以调用一些方法来操作数据:步骤为:1.创建一个String类型的实例,2.调用指定方法3.销毁实例)
引用类型和基本包装类型
区别在于对象的生存期:引用类型的实例,在执行流离开当前作用域之前都一直保持在内存中;自动创建的基本包装类型的对象,只在代码执行的瞬间,之后立即销毁;这意味着我们不能在运行时为基本类型添加属性和方法;
对于基本包装类型的实例调用typeof会返回“object”;布尔运算时所有对象都会被转化为true
Object 构造函数也会向工厂方法一样,返回相应基本包装类型的实例
typeof(Number(value))//转型函数,“number”;typeof(new Number(value)//构造函数,“object”;
Boolean类型
var bObject = new Boolean(true)
Boolean类型重写了valueOf方法,返回基本类型true或false,重写了toString()方法,返回字符串“true”“false”;
检测布尔对象结果为(建议永远不要使用Boolean对象) 重点内容
typeof falseObject; //object
typeof falseValue; //boolean
falseObject instanceof Boolean; //true
falseValue instanceof Boolean;//false
Number类型
var numberObject = new Number(10);
与Boolean类型类似也重写了valueOf方法,返回基本类型的数值,重写了toString()方法,返回字符串形式的数值;另外toString()还可以传递一个表示基数的参数,告诉返回几进制数值的字符串;
数值格式化为字符串的方法
toFixed()方法
按照指定的小数位返回数值的字符串表示;传入的数字表示几位小数
toExponential()方法
传入的参数表示输出结果中的小数位数10.toExponential(1);//"1.0e+1"
toPrecision() 方法
可能返回固定大小格式(fixed),也可能返回指数格式(exponential)具体看哪种格式合适。该方法接受一个参数,表示所有数字的位数(不包含指数部分)
不建议直接实例化Number类型
var num = 99;
num.toPrecision(1);//"1e+2"
num.toPrecision(2);//"99"
num.toPrecision(3);//"99.0"
String 类型
可以使用构造函数创建
var stringObject = new String("hello world");
String 对象的方法可以在所有基本的字符串值访问到。其中valueOf()、toLoacleString()、toString()方法,都返回对象表示的基本字符串值
length:即使字符串中包含双字节字符(不是占一个字节的ASCII字符,每个字符仍然算一个字符,即”高兴”.length;//2)
字符方法
访问字符串中特性字符的方法:charAt()和charCodeAt(),参数为基于0的字符位置;
charAt() 以单字符字符串的形式返回给定位置的那个字符, "高兴".charAt(1);//'兴'
charCodeAt()返回字符编码
字符串操作方法
concat:将一或多个字符串拼接其阿里,返回新字符串(实践中更多是用加号操作符)
slice、substr、substring方法,(可以接收一或两个参数,不会改变原始字符串)第一个参数都是指定字符串的开始位置
其中slice和substring方法,第二个参数指定的是子字符串到哪里结束,而substr则为返回的字符个数;如果没有第二个参数,则将字符串的长度作为结束位置.
在传递参数为负值的时候,他们的行为不仅相同
其中slice()会将传入的负值与字符串的长度相加,substr会将负的第一个参数加上字符串长度,负的第二个值转换为0,substring会将所有的负值转换为0;
substring(3,0)//这个方法会从较小的数开始,相当于substring(0,3),slice 不行;slice(4,3)会得到空字符串
字符串的位置方法
indexOf和lastIndexOf,从字符串中搜索给定的子字符串,然后返回子字符串的位置,如果没有找到则返回-1;不过一个从前向后搜索(indexOf),一个从后向前(lastIndexOf)
可以接收第二个参数,表示字符串从哪个位置开始搜索
在使用第二个参数的情况下,可以通过循环调用indexOf或lastIndexOf来找到所有匹配的子字符串
//关键为
pos = stringValue.indexOf("e",pos+1);
trim()方法
会创建一个字符串的副本,删除前置和后缀的所有空格,然后返回结果
字符串大小写转换方法
toLowerCase、toLocaleLowerCase、toUpperCase、toLocaleUpperCase
在不知道代码将在哪种语言中运行时,使用这对时区的方法更为稳妥
字符串的模式匹配方法
match()方法,本质上和RegExp的exec()方法相同,这个方法只接受一个参数,要么是正则表达式,要么是一个RegExp对象;返回一个数组,与exec方法相同
search()方法,与match方法参数相同,返回字符串第一个匹配项的索引,如果没有,将返回-1;始终是从字符串开头向后查找模式
replace () 方法接收两个参数:第一个参数可以是一个RegExp或字符串(不会被转换成正则表达式),第二个参数可以是一个字符串或者函数,如果第一个参数是字符串,只会替换第一个子字符串,想要替换所有子字符串,只能提供一个正则表达式,而且要有全局指定标志;第二个参数可以使字符串,也可以使一些特殊的字符序列;
字符序列 |
替换文本 |
$$ |
$ |
$& |
匹配整个模式的字符串 |
$’ |
匹配子字符串之前的子字符串 |
$` |
匹配子字符串之后的子字符串 |
$n |
匹配第n个捕获的子字符串,0~9,没有定义捕获组则是空字符串 |
$nn |
匹配第nn个捕获的子字符串,01~99没有定义捕获组则是空字符串 |
replace 方法的第二个参数可以是一个函数,在只有一个匹配项的情况下,向函数传递三个参数,模式的匹配项,其在字符串的位置,原始字符串
split方法
基于指定的分隔符将字符串分割为多个子字符串,并放入一个数值中,分隔符可以是字符串,也可以是RegExp对象,这个方法不会将字符串看成正则表达式,split可以接收第二个参数,用于指定数值的大小,以确保返回的数组不会超过既定大小
localeCompare 方法
比较两个字符串,字符串在字母表中排在字符串参数之前,则返回一个负数,相等,则返回0,之后,则为正数
formCharCode方法
接收一或多个字符编码,转换成一个字符串,charCodeAt的反操作
单体内置对象
在ECMAScript执行前就有,不用显示实例化
- Global对象
编码方法
encodeURI()和encodeURIComponent()方法可以对URI进行编码,以便发送给浏览器
encodeURI:主要用于整个uri,不会对本身属于uri的特殊字符进行编码,如冒号,正斜杠,问号和#号
encodeURIComponent:主要用于uri的某一段进行编码,会对他发现的任何非标准字符进行编码
对应解码为decodeURI 和decodeURIComponent
eval()方法
只接受一个参数,要执行的ECMAScript字符串,像是一个完整的ECMAScript解析器
不要使用,在严格模式下,外部访问不到任何在eval中创建的函数和变量
Global对象的属性
属性 |
说明 |
属性 |
说明 |
undefined |
特殊值undefined |
Date |
构造函数Date |
NaN |
特殊值NaN |
RegExp |
构造函数RegExp |
Infinity |
特殊值Infinity |
Error |
构造函数Error |
Object |
构造函数Object |
EvalError |
构造函数EvalError |
Array |
构造函数Array |
RangeError |
构造函数RangeError |
Function |
构造函数Function |
ReferenceError |
构造函数ReferenceError |
Boolean |
构造函数Boolean |
SyntaxError |
构造函数SyntaxError |
String |
构造函数String |
TypeError |
构造函数TypeError |
Number |
构造函数Number |
URIError |
构造函数URIError |
window 对象
全局作用域中声明的所有变量和函数,都成了window对象的属性
Math对象
Math对象的属性
E、LN10、LN2、LOG2E、LOG10E、PI、SQRT1_2、SQRT2
min和max方法
传入任意多个数值参数
求数组的最大值、最小值Math.max.apply(Math,Array);
舍入方法
Math.ceil() 执行向上舍入
Math.floor() 执行向下舍入
Math.round() 执行标准舍入
random 方法
function (lower,upper){
var choice = upper - lower;
return Math.floor(Math.random()*choice+lower);
}