《JavaScript高级程序设计》学习笔记(第五章)

来源:互联网 发布:内存数据库有哪些 编辑:程序博客网 时间:2024/06/05 15:04

本笔记总结《JavaScript高级程序设计》一书的前七章内容,旨在提高作者的姿势水平,笔记内容仅供参考。


引用类型

详尽介绍了JavaScript内置的所有引用类型,如Object和Array。这一章对ECMA-262规范中描述的每一种引用类型既做了理论上的阐释,又从浏览器实现的角度给出了介绍。


Object类型

创建Object实例的两种方式:第一种,使用new操作符后跟Object构造函数,如下:
var person = new Object();person.name = "Nicholas";person.age = 29;

另一种方式是使用对象字面量表示法,如下:
var person = {    name : "Nicholas",    age : 29}

访问对象属性的方法:
alert(person["name"]);  //方括号表示法alert(person.name);      //点表示法
方括号语法的主要优点是可以是通过变量来访问属性,如下:
var propertyName = "name";alert(person[propertyName]);  //"Nicholas"
通常,除非必须使用变量来访问属性,否则我们建议使用点表示法。


Array类型

ECMAScript数组的每一项可以保存任何类型的数据。

创建数据的基本方式有两种:第一种,使用Array构造函数,如下:

var colors = new Array();var colors = new Array(20);    //传递数组数量var colors = new Array("red","blue","green");    //传递项

第二种,使用数组字面量法,如下:

var colors = ["red","blue","green"];    //创建一个包含3个字符串的数组var names = [];    //创建一个空数组var values = [1,2, ];    //禁忌,会创建一个包含2或3项的数组var options = [ , , , , ,];    //禁忌,会创建一个包含5或6项的数组

检测数组:

自从ECMAScript 3做出规范以后,就出现了确定某个对象是不是数组的经典问题。对于一个网页或者一个全局作用域而言,使用instanceof操作符就能得到满意的结果:

if (value instanceof Array){    //对数组执行某些操作}
如果网页中包含多个框架,那实际上就存在两个以上不同的全局执行环境,从而存在两个以上不同版本的Array构造函数。如果你从一个框架向另一个框架传入一个数组,那么传入的数组与在第二个框架中原生创建的数组分别具有各自不同的构造函数。

ECMAScript 5 新增了Array.isArray()方法,这个方法的目的是最终确定某个值到底是不是数组,而不管它是在哪个全局执行环境中创建的。

if (Array.isArray(value)){    //对数组执行某些操作}

转换方法:

toLocaleString:使用地区特定的分隔符把生成的字符串链接起来,形成一个字符串

toString()方法:返回由数组中每个值的字符串形式拼接而成的一个以逗号分隔的字符串。

valueOf()方法:返回数组。



栈方法:

栈是一种LIFO(Last-In-First-Out)的数据结果,也就是最新添加的项最早被移除。ECMAScript为数组专门提供了push()和pop()方法,以便实现类似栈的行为。

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

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



队列方法:

队列数据的访问规则是FIFO(First-In-First-Out)。队列在列表的末端添加项,从列表的前端移除项。

shift()方法,移除数组中的第一个项并返回该项,同时将数组长度减少1。结合使用shift()和push()方法,可以项使用队列一样使用数组。

unshift()方法用途相反,在数组前端添加任意个项并返回新数组的长度。使用unshift()和pop()方法,可以从相反的方向来模拟队列,即在数组的前端添加项,从数组末端移除项。



重排序方法:

存在两个可以直接用来排序的方法:reverse()和sort()。

reverse():反转数组项的顺序,如下:

var values = [1, 2, 3, 4, 5];values.reverse();alert(values);  //5,4,3,2,1

升序方法:

function compare(value1, value2) {    if (value1 < value2) {        return -1;    ) else if (value1 > value2) {        return 1;    ) else {        return 0;    )}var values = [0, 1, 5, 10 ,15];values.sort(compare);alert(values);    //0,1,5,10,15

降序方法:

function compare(value1, value2) {    if (value1 < value2) {        return 1;    ) else if (value1 > value2) {        return -1;    ) else {        return 0;    )}var values = [0, 1, 5, 10 ,15];values.sort(compare);alert(values);    //15,10,5,1,0


操作方法:

concat()方法:基于当前数组中的所有项创建一个新数组。如果传递给concat()方法的是一或多个数组,则该方法会将这些数组中的每一项都添加到结果数组中。如果传递的值不是数组,这些值就会被简单地添加到结果数组的末尾。


slice()方法:一个参数的情况下,该方法返回从该参数指定位置开始到当前数组末尾的所有项。如果有两个参数,该方法返回起始和结束位置之间的项——但不包括结束位置的项。


splice()方法:

删除:指定两个参数——要删除的第一项的位置和要删除的项数。如,splice(0,2)会删除数组中的前两项。

插入:指定三个参数——起始位置、0(要删除的项数)和要插入的项。如,splice(2,0,"red","green")会从当前数组的位置2插入两个字符串。

替换:指定三个参数——起始位置、要删除的项数和要插入任意数量的项。如,splice(2,1,"red","green")会删除当前数组位置2的项,然后再从位置2插入两个字符串。



位置方法:接收两个参数——要查找的项和(可选的)表示查找起点位置的引索。

indexOf():从数组的开头(位置0)开始向后查找。

lastIndexOf():从数组的末尾开始向前查找。



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

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

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

var numbers = [1,2,3,4,5,4,3,2,1];var filterResult = numbers.filter(function(item, index, array){    return (item > 2);});alert(filterResult);    //[3,4,5,4,3]


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

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

var numbers = [1,2,3,4,5,4,3,2,1];var mapResult = numbers.map(function(item, index, array){    return item * 2;});alert(mapResult);    //[2,4,6,8,10,8,6,4,2]


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



归并方法:两个归并数组的方法:reduce()和reduceRight()。这两个方法都会迭代数组的所有项,然后构建一个最终返回的值。reduce()方法从数组的第一项开始,逐个遍历到最后。而reduceRight()则从数组的最后一项开始,向前遍历到第一项。这两个方法都接收两个参数:一个在每一项上调动的函数和(可选的)作为归并基础的初始值。传给方法的函数接收4个参数:前一个值、当前值、项的索引和数组对象。如下为用reduce()方法执行求和操作:

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


Date类型

Date类型使用自UTC 1970年1月1日午夜(零时)开始经过的毫秒数来保存日期,保存的日期可以精确到1970年1月1日之前或之后的100 000 000年。

如果想根据特定的日期和时间创建日期对象,必须传入表示该日期的毫秒数。为了简化这一过程ECMAScript提供两个方法:Date.parse()和Date.UTC()。

Date.parse()方法接收一个表示日期的字符串参数,然后尝试根据这个字符串返回相应日期的毫秒数。将地区设置为美国的浏览器通常都接受下列日期格式:月/日/年,如6/13/2017;英文月名 日,年,如May 12,2017。例如,要为2017年8月18日创建一个日期对象,可以使用下面的代码:

var someDate = new Date(Date.parse("Augest 18,2017"));
如果传入的字符串不能表示日期,那么它会返回NaN。如果直接将表示日期的字符串传递给Date构造函数,也会在后台调用Date.parse()。如下:
var somDate = new Date("Augest 18,2017");    //将得到与前面相同的日期对象

Date.UTC()方法也返回表示日期的毫秒数,它的参数分别是年份,基于0的月份(一月是0,以此类推)、月中的哪一天(1~31)、小时数(0~23)、分钟、秒以及毫秒数。这些参数只有年和月是必需的。若没有提供月中的天数,则假设天数为1;若省略其他参数,则统统假设为0,如下:

var y2k = new Date(Date.UTC(2017, 0));    //GMT时间2017年1月1日午夜零时var now = new Date(Date.UTC(2017,9,9,16,37,00));    //GMT时间2017年10月9日16点37分

Date.now方法返回调用这个函数时的日期和时间毫秒数。在不支持的浏览器上面,可以使用+操作符获取Date对象时间戳:

var start = +new Date();    //取得开始时间doSomething();    //调用函数var stop = +new Date(),    //取得停止时间    result = stop -start;  

日期格式化方法:

toDateString()——以特定于实现的格式显示星期几、月、日、年;

toTimeString()——以特定于实现的格式显示时分秒和时区;

toLocaleDateString()——以特定于地区的格式显示星期几、月、日和年;

toLocaleTimeString()——以特定于地区的格式显示时分秒;

toUTCString()——以特定于实现的格式完整的UTC日期。



Function类型

函数是对象,函数名是指向函数对象的指针。


没有重载:

var addSomeNumber = function (num){    return num + 100;};addSomeNumber = function (num){    return num + 200;};var result = addSomeNumber(100);    //300
在创建第二个函数时,实际上覆盖了引用了第一个函数的变量addSomeNumber。


函数声明和函数表达式:

function funDeclaration(type){    return type === "Declaration";}    //函数声明var funExpression = function(type){    return type === "Expression";}    //函数表达式

函数内部属性:两个特殊对象:arguments和this。arguments有一个名叫callee的属性,指向拥有这个arguments对象的函数。如下阶乘:

function factorial(num){    if (num <=1) {        return 1;    } else {        return num * factorial(num-1)    }}    //函数的执行与函数名factorial耦合function factorial(num){    if (num <=1) {        return 1;    } else {        return num * arguments.callee(num-1)    }}    //改变函数的名字,也可以正常完成递归调用


this引用的是函数据以执行的环境对象。

另一个函数对象的属性:caller,保存着调用当前函数的函数的引用。


函数属性和方法:

每个函数都包含两个非继承而来的方法:apply()和call()。

apply()方法接收两个参数:一个是在其中运行函数的作用域,另一个是参数数组,如下:

function sum(num1,num2){    return num1 + num2;}function callSum1(num1,num2){    return sum.apply(this,arguments);}function callSum2(num1,num2){    return sum.apply(this,[num1,num2]);}alert(callSum1(10,10);    //20alert(callSum2(10,10);    //20

call()方法和apply()方法的作用相同,它们的区别仅在于接受参数的方法不同。在使用call()方法时,传递给函数的参数必须逐个列举出来。

function sum(num1,num2){    return num1 + num2;}function callSum(num1,num2){    return sum.call(this, num1, num2);}alert(callSum(10,10);    //20

传递参数并非这两个方法的真正用武之地,它们真正强大的地方是能够扩充函数赖以运行的作用域,如下:

window.color = "red";var o = {color:"blue"};function sayColor(){    alert(this.color);}sayColor();    //redsayColor.call(this);    //redsayColor.call(window);    //redsayColor.call(o);    //blue

基本包装类型

Boolean、Number和String。

对基本包装类型的实例调用typeof会返回“object”,而且所有基本包装类型的对象都会被转换为布尔值true。

 

String类型:

var stringValue = "hello world";alert(stringValue.charAt(1));    //"e"alert(stringValue.charCodeAt(1));    //字符编码101alert(stringValue[1]);    //"e"

var stringValue = "hello ";var result = stringValue.concat("world");alert(result);    //"hello world"alert(stringValue);    //"hello"


match(),search()这两个方法均接收一个参数,字符串或者RegExp对象指定的一个正则表达式。

replace()方法,接收两个参数,第一个参数可以是一个RegExp对象或字符串(不会被转换成正则表达式),第二个参数可以是一个字符串或函数,若要替换所有字符串,则必须使用正则表达式,并加全局(g)标志。

split(),接收一个参数作为字符串的分隔符,返回由分隔符分隔得到的数组,可以接收第二个可选参数,作为返回结果的数组大小

localeCompare(),比较两个字符串,关于是否区分大小写,视地区而定。

Math对象

min(),max(),ceil()向上舍入,floor()向下舍入,round()标准舍入,即四舍五入,random()返回大于等于0小于1的随机数。

阅读全文
0 0
原创粉丝点击