1.引用类型的值(对象)是引用类型的一个实例。在ECMAScript中,**引用类型是一种数据结构,用于将数据和功能组织在一起**。它也常被称为类,但这种称呼并不妥当。尽管ECMAScript从技术上讲是一门面向对象的语言,但它并不具备传统的面向对象语言所支持的类和接口等基本结构。引用类型有时候也被称为**对象定义**,因为它们描述的是一类对象所具有的属性和方法。
2.创建Object实例的方式有两种。第一种是**使用new操作符后跟Object构造函数**,另一种方式是使用**对象字面量**表示法。
~~~
var person = {
name : ‘Ken’,
age : 29
};
~~~
在这个例子中,左边的花括号表示对象字面量的开始,因为它出现在了**表达式上下文**中。ECMAScript中的表达式上下文指的是能够返回一个值(表达式)。赋值操作符表示后面是一个值,所以左花括号在这里表示一个表达式的开始。同样的花括号,如果出现在一个**语句上下文**中,例如跟在if语句条件的后面,则表示一个语句块的开始。
3.***在使用对象字面量语法时,属性名也可以使用字符串***。如下面这个例子所示:
~~~
var person = {
'name' : 'ken',
'age' : 29,
5 : true
}
~~~
**这里的数值属性名会自动转换为字符串**。
***对象字面量传递参数的模式最适合需要向函数传入大量可选参数的情形。一般来讲,命名参数虽然容易处理,但在有多个可选参数的情况下就会显示不够灵活。最好的做法是对那些必需值使用命名参数,而使用对象字面量来封装多个可选参数***。
4.ECMAScript数组的每一项可以保存任何类型的数据。
5.创建数组的基本方式有两种。
第一种是使用Array构造函数(new也可以省略)。可以给构造函数传入一个数值,这个数值会自动变成length属性的值;也可以像Array构造函数传递数组中应该包含的项。
第二种基本方式是使用数组字面量表示法。数组字面量由一对包含数字项的方括号表示,多个数组项之间以逗号隔开。
6.***数组的length属性很有特点--它不是只读的。因此通过设置这个属性,可以从数组的末尾移除项或向数组添加新项(undefined)。***
***利用length属性也可以方便地在数组末尾添加新项***,如下所示:
`colors[colors.length] = ‘black’; //数组的最后一项永远是[length-1]`
7.Array.isArray()方法用于最终确定某个值到底是不是数组。这是因为在不同 iframe 中创建的 Array 并不共享 prototype,所以instanceof无法检测。
8.数组转换方法
调用数组的***toString()***方法会返回由数组中每个值的字符串形式拼接而成的一个以逗号分隔的字符串。如果使用***join()***方法,则可以使用不同的分隔符来构建这个字符串。join()方法只接受一个参数,即用作分隔符的字符串。如果传入空字符串,则直接拼接;如果不传入任何值,则使用逗号作为分隔符。
9.数组栈方法(FILO)
***push()***方法可以接收任意数量的参数,把它们添加到数组的末尾,并返回修改后的数组长度。而***pop()***方法则从数组末尾移除最后一项,然后返回移除的项。
10.数组队列方法(FIFO)
正向队列:***push() + shift()***
反向队列:***unshift + pop()***
11.添加项的方法都可以添加任意项并返回数组长度。删除项方法都返回被删除的那一项。
12.数组重排序方法:
***reverse()*** 反转数组项的顺序
***sort()*** 可以传入一个比较函数,比较函数接收两个参数,如果第一个参数应该位于第二个**之前则返回一个负数**,如果两个参数相等则返回0,如果第一个参数应该位于第二个参数**之后则返回一个正数***。
如果数组项是数值类型或者其valueOf)方法会返回数值类型的对象类型,可以使用更简单的比较函数。以下这个函数将数组由大到小重排序。
~~~
function compare(a,b) {
return b-a;
}
~~~
13.数组操作方法
***concat()*** 用于获取合并后的数组。(不是contact)该方法可以基于当前数组中的所有项创建一个副本,然后将接受到的参数添加到这个副本的末尾,最后返回新构建的数组。可以传入多个数组或值。调用这个方法的数组维持原值不变。
***slice()*** 用于获取数组的子数组。该方法可以接受一个或两个参数,即要返回项的起始位置和结束位置。在只有一个参数的时候,slice()方法返回从该参数指定位置开始到当前数组末尾的所有项。如果有两个参数,该方法返回起始和结束位置之间的项--但不包括结束位置的项。slice()方法同样不会影响原始数组。
如果slice()方法的参数中有负数,则用数组长度加上该数来确定相应的位置。如果结束位置小于起始位置,则返回空数组。
***splice()*** 用于删除、插入、替换数组元素。语法:
splice(起始位置,要删除的项数,插入的新项)
splice()方法始终会返回一个数组,该数组包含从原始数组中删除的项。如果没有删除任何项则返回一个空数组。
14.数组位置方法
***indexOf()***和***lastIndexOf()***用于查找某个值在数组中第一次出现的索引值。这两个方法都接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。这两个方法都返回要查找的项在数组中的位置,或者在没有找到的情况下返回-1。
**注意:这两个方法返回的位置始终是从0开始以正序排列的索引。查找起点的索引位置包括了起点本身。**
15.数组迭代方法
***every()***:对数组中的每一项运行给定函数,如果该函数对每一项都返回true,则返回true;
***some()***:对数组中的每一项运行给定函数,如果该函数任一项返回true,则返回true。
***filte()***:对数组中的每一项运行给定函数,返回该函数会返回true的项组成的数组。
***forEach()***:对数组中的每一项运行给定函数。这个方法没有返回值。
***map()***:对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。
语法:array.xxx(function(item,index,thisArray){
//return do something
},作用域对象(可选))
**注意:迭代方法不会对原数组造成任何影响。forEach()和对数组进行for循环的不同之处也在于此。**
16.数组归并方法(**用于条件筛选统计**)
***reduce()***和***reduceRight()***。
语法:array.xxx(function(acc,cur,index,thisArray){
//return do something;
},归并基础的初始值(可选))
若不传入归并基础值,则acc为数组第一项
**传入函数的return值将作为下次循环的prev值。**
17.要创建一个日期对象,使用new操作符和Date构造函数即可,
var now = new Date();
在调用Date构造函数而不传入参数的情况下,新创建的对象自动获得当前日期和时间。
18.设定时间-如果想根据特定的日期和时间创建日期对象,必须传入表示该日期的毫秒数(即从UTC时间1970年1月1日午夜起至该日期止经过的毫秒数)。为了简化这一计算过程,ECMAScript提供了两个方法:
18.1 Date.parse():因为地区格式及浏览器实现的差异,不推荐使用此方法。
18.2 Date.UTC():下例中,只有年和月这两个参数是必须的,其他缺省值默认为最小。
~~~
//GMT时间2005年5月5日下午5时55分55秒
var time = new Date(Date.UTC(2005,4,5,17,55,55));
~~~
在创建Date()函数时传入参数,将会在后台调用Date.UTC()方法,但与Date.UTC()不同,直接传入构造函数创建的时间基于**本地时区**而非GMT。
18.***Date.now()返回表示调用这个方法时的日期和时间的毫秒数(即时间戳)***。注意,这个方法仅返回毫秒数,不能对其调用Date()对象的其他方法。调用这个方法而非new一个新的Date()对象有助于提高程序的运行效率、减少内存占用。
19.Date类型的valueOf()方法返回日期的毫秒表示,因此可以方便使用比较操作符来比较日期大小。
20.常用日期/时间组件方法
**getTime()** 返回表示日期的毫秒数;与valueOf()方法返回的值相同
**setTime()** 以毫秒数设置日期,会改变整个日期
**getFullYear()** 取得4位数的年份
**getMonth()** 返回日期中的月份,其**中0表示1月,11表示十二月**
**getDate()** 返回日期月份的天数(1到31)
**getDay()** 返回日期中星期的星期几(其中**0表示星期日0,6表示星期六**)
**getHours()**
**getMinutes()**
**getSeconds()**
21.正则表达式基本语法:
var expression = /pattern/ flags;
其中标志位可以为以下表示:
g - 表示全局模式,即模式将被应用于所有字符串,而非在发现第一个匹配项时立即停止。
i - 表示不区分大小写,即在匹配项时忽略模式与字符串的大小写。
m - 表示多行模式,即在到达一行文本末尾时还会继续查找下一行中是否存在与模式匹配的项。
22.模式中的所有元字符都必须转义。
23.RegExp实例方法:
RegExp对象的主要方法是exec(),该方法是专门为捕获组而设计的。exec()接受一个参数,即要应用模式的字符串,然后返回包含第一个匹配信息的数组;或者在没有匹配项的情况下返回null。返回的数组虽然是Array的实例,但包含两个额外的属性:index和input。其中index表示匹配项在字符串中的位置,而input表示应用正则表达式的字符串。在数组中,第一项是与整个模式匹配的字符串,其他项是与模式中的捕获组匹配的字符串(如果模式中没有捕获组,则该数组只有一项)。
对于exec()方法而言,即使在模式种设置了全局标志,它每次也只会放回一个匹配项。在不设置全局标志的情况下,在同一个字符串上多次exec()将始终返回第一个匹配项的信息。而在设置全局标志的情况下,每次调用exec()则都会在字符串中继续查找新匹配项。
正则表达式的第二个方法是***test()***,它接受一个字符串参数。在模式与该参数匹配的情况下返回true,否则返回false。因此,***test()方法经常被用在if语句中,这种用法经常出现在验证用户输入的情况下***。
24.RegExp构造函数属性,使用这些属性可以从exec()或test()执行的操作中提取出更具体的信息。
25.函数实际上是对象,每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法。由于函数是对象,因此函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定。
26.函数通常是使用函数声明语法定义的。这与使用函数表达式的定义方式几乎相差无几。最后一种定义函数的方式是使用Function构造函数。Function构造函数可以接收任意数量的参数,但最后一个参数始终都被看成是函数体,而前面的参数则枚举出了新函数的参数。例:
`var sum = new Function(‘num1’,’num2’,’return num1+num2’); //不推荐`
27.**不仅可以像传递参数一样把一个函数传递给另一个函数,而且可以将一个函数作为另一个函数的结果返回**。例:
~~~
function callSomeFunction(someFunction, someArgument){
return someFunction(someArgument);
}
~~~
**甚至我们还可以从一个函数中返回另一个函数,而不是函数的运行结果,而且这也是极为有用的一种技术。详见P113**
28.***arguments对象还有一个名叫callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数。该属性常用于解除函数执行与函数名之间的强耦合。***
29.arguments.callee.caller返回调用当前函数的函数的引用。
30.**apply()**和**call()**方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内的this对象的值。
apply()方法接收两个参数:一个是在其中运行函数的作用域,另一个是参数数组。其中,**第二个参数可以是Array的实例,也可以是arguments对象。而call()方法传递给函数的参数必须租个列举出来。**使用apply()还是call()完全取决于你采用哪种给函数传递参数的方式最方便。
~~~
function sum(num1,num2){
return num1+num2;
}
function callSum1(num1,num2){
return sum.apply(this,arguments);
//等同于 return sum.apply(this,[num1,num2]);
}
~~~
**注意,全局函数的this为window对象。用这两个方法来扩充作用域的最大好处是,对象不需要与方法有任何耦合关系。**
31.***bind()***方法会创建一个函数的实例,其this值会被绑定到传给bind()函数的值。例:
~~~
window.color = ‘red’;
var o = {color:’blue’};
function sayColor(){
alert(this.color)
}
var objectSayColor = sayColor.bind(o);
objectSayColor(); //blue
~~~
32.数值类型的toFixed()方法可把 Number 四舍五入为指定小数位数的数字,返回数值的字符串表示。能够自动舍入的特性,使得这个方法很适合处理货币值。例:
~~~
var num = 10;
alert(num.toFixed(2)); //10.00
~~~
33.String类型的每个实例都有一个length属性,表示字符串中包含的字符数。即使字符串中包含双字节字符(不是占一个字节的ASCII),每个字符也仍然只算一个字符。
34.String类型字符方法:
***charAt()***、***charCodeAt()***这两个方法都接收一个参数,即基于0的字符位置。其中前者以单字符串的形式返回给定位置的那个字符。后者返回该字符的字符编码。
35.String类型字符串操作方法:
concat() 用于将一或多个字符串拼接起来,返回拼接得到的新字符串。(相当于+操作符)
***slice()***、***substr()***、substring()这三个方法都会返回被操作字符串的一个子字符串,而且也都接受一或者两个参数。第一个参数指定字符串的开始位置,第二个参数表示字符串到哪里结束。这三个方法对原始字符串不会造成影响。
***slice()***接受两个参数,即起始位置与终点位置;
***substr()***接受两个参数,即起始位置与字符串长度;
substrting()使用场景比较小,区间取值,可逆向
36.String类型位置方法:
***indexOf()、lastIndexOf()***用于从字符串中查找子字符串。这两个方法都可以接受可选的第二个参数,表示从字符串中哪个位置开始搜索(第二个参数均以正序指示)。
37.String类型trim()方法:
***trim()***方法会返回一个字符串的副本,删除前置及后缀的所有空格。
38.String类型字符串大小写转换方法:
***toUpperCase()、toLowerCase()***直接作用于调用该方法的字符串本身。
39.String类型字符串的模式匹配方法:
match()方法等同于RegExp类型的exec()方法。
search()方法返回字符串中第一个匹配项的索引,如果没有匹配项则返回-1。
***replace()***方法用于替换子字符串。这个方法接受两个参数:第一个参数是一个RegExp对象或者一个字符串(这个字符串不会被转换成正则表达式),第二个参数可以是一个字符串或者一个函数。如果第一个参数是字符串,那么只会替换第一个子字符串。要想替换所有子字符串,唯一的办法就是提供一个正则表达式,而且要指定全局标志。
***split()***方法可以基于指定的分隔符将一个字符串分割成多个子字符串,并将结果放在一个数组中。分隔符可以是字符串,也可以是一个RegExp对象(这个方法不会将字符串视为正则表达式)。这个方法可以接受第二个参数,用于指定返回数组的长度。如果把空字符串 ("") 用作 分隔符,那么stringObject中的每个字符之间都会被分割。如果传入的分隔符不存在,则返回原字符串。
40.ECMA-262对内置对象的定义是:“由ECMAScript实现提供的、不依赖于宿主环境的对象,这些对象在ECMAScript程序执行之前就已经存在了。”意思就是说,开发人员无需显式地实例化内置对象,因为它们已经实例化了。前面我们已经介绍了大多数内置对象,例如Object、Array、String。ECMAScript还定义了两个单体内置对象:Global和Math。
41.所有在全局作用域中定义的属性和函数,都是Global对象的属性。在浏览器环境下,Global对象是window对象的一部分。
42.***encodeURI()***和***encodeURIComponent()***方法可以对Uniform Resource Identifiers(通用资源标识符)进行编码,以便发送给浏览器。其中encodeURI()主要用于整个URI,而encodeURIComponent()主要用于对URI中的某一段进行编码。它们的主要区别在于,前者不会对本身属于URI的特殊字符进行编码,例如冒号、正斜杠、问号和井号;而后者则会对他发现的任何非标准字符进行编码。
***一般来说,我们使用encodeURIComponent()方法的时候要比使用encodeURI()更多,因为在实践中更常见的是对查询字符串参数而不是对基础URI进行编码。***
它们的逆向方法分别是decodeURI()和decodeURIComponent()。
43.eval()方法就像是一个完整的ECMAScript解析器,它只接受一个参数,即要执行的ECMAScript**字符串**。
当解析器发现代码中调用eval()方法时,他会将传入的参数当作实际的ECMAScript语句来解析,然后把执行结果插入到原来的位置。**通过eval()执行的代码被认为是包含该次调用的执行环境的一部分,因此被执行的代码具有与该执行环境相同的作用域链。**这意味着通过eval()执行的代码可以引用在包含环境中定义的变量。
在eval()中创建的任何变量或函数都不会被提升,因为在解析代码的时候,它们被包围在一个字符串中;它们只在eval()执行时创建。
44.Math对象的**min()**和**max()**方法
这两个方法用于确定一组数值中的最小值和最大值。这两个方法都可以接收任意多个数值参数。要找到数组中的最大或最小值,可以使用apply()方法:
~~~
var values = [1,2,3,4];
var result = Math.max.apply(Math,values);
~~~
45.Math对象的舍入方法
Math.ceil() 向上取整
Math.floor() 向下取整
Math.round() 四舍五入取整
46.Math.random()方法返回大于等于0小于1的一个随机数。