JS基础知识回顾:引用类型(一)

在ECMAScript中引用类型是一种数据结构,用于将数据和功能组织在一起,而对象时引用类型的一个实例。

尽管ECMAScript从技术上讲是一门面向对象的语言,但它不具备传统的面向对象语言所支持的类和接口等基本结构,所以虽然说引用类型与类看起来想死,但他们并不是相同的概念。

不过引用类型有的时候也可以被称为对象定义,因为他们描述的是一类对象所具有的属性和方法。

新对象是使用new操作符后跟一个构造函数来实现的,构造函数本身就是一个函数,只不过该函数时处于创建新对象的目的而定义的。

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

Object是ECMAScript中使用最多的一个类型,虽然Object的实例不具备多少功能,但对于在应用程序中存储和传输数据而言,它们确实是非常理想的选择。

创建Object实例的方式有两种:

使用new操作符后跟Object构造函数,例如:var person=new Object();person.name="Name";person.age=29;

还可以使用对象字面量表示法,需要注意的是利用对象字面量表示法表示对象时最后一个属性后面不能添加逗号,否则在IE7及更早版本及Opera中会导致错误。

对象字面量是对象定义的一种简写形式,目的在于简化创建包含大量属性的对象的过程,例如:var person={name:"Name",age:29};

在使用对象字面量语法时,属性名可以使用字符串或数字,不过数字属性名会被自动转换为字符串,例如:var person={"name":"Name","age":29,5=true}

在使用对象字面量语法时,如果留空花括号,则可以定义值包含默认属性和方法的对象,例如:var person={};//与new Object()相同 person.name="Name";person.age=29;

在通过对象字面量定义对象时,实际上并不会调用Object构造函数(Firefox2及之前的版本会调用,但Firefox3之后就不会了)。

在实际应用中,人们往往更倾向于使用对象字面量语法,因为这种语法要求的代码量少,而且能够给人封装数据的感觉。

对象字面量也是向函数传递大量可选参数的首选方式,例如:

function displayInfo(args){

  var output="";

  if(typeof args.name=="string"){output+="Name:"+args.name+"\n";}

  if(typeof args.age=="number"){output+="Age:"+args.age+"\n";}

  alert(output);

}

displayInfo({name:"Nicholas",age:29});

displayInfo({name:"Greg"});

一般来说,访问对象属性时使用的都是点表示法,不过在JavaScript中也可以使用方括号来表示访问对象的属性,例如:

alert(person.name);//"Nicholas"(除非必须使用变量来访问属性,否则建议使用点表示法)

alert(person["name"]);//"Nicholas"(方括号表示法可以在方括号中写属性名)

alert(person[propertyName]);//"Nicholas"(方括号表示法也可以在方括号中写变量名)

person["first name"]="Nicholas";(在属性名当中有空格等非字母数字的字符时用点表示法会报错,所以最好用方括号表示法)

Array类型在ECMAScript中用来表示数组,与其他语言不同的是,ECMAScript数组的每一项可以保存任何类型的数据,且数组的大小是可以动态调整的。

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

第一种方式是使用Array构造函数,例如:var colors=new Array();

如果预先知道了数组的长度,也可以给构造函数传递该数量,而该数量会自动变成数组的length属性的值,例如:var colors=new Array(20);

也可以像Array构造函数传递数组中应该包含的项,例如:var colors=new Array("red","blue","green");

当只给构造函数传递一个值时,如果该值是一个数字,则会按照该数值创建包含给定项数的数组,如果传入的是其他类型的参数,则会创建包含那个值的只有一项的数组。

另外在创建Array构造函数时也可以省略new操作符,例如:var colors=Array(3);var names=Array("Greg");

第二种方式是使用数组字面量表示法,数组字面量由一对包含数组项的方括号表示,多个数组项之间用逗号隔开,例如:

var colors=["red","blue","green"];//创建一个包含三个字符串的数组

var names=[];//创建一个空数组

var values=[1,2,]//不建议使用,在IE8及之前版本会创建包含三个项目每项的值分别为1,2,undefined的数组,其他浏览器中会创建包含1,2两项的数组

var options=[,,,,,]//不建议使用,在IE8及之前版本会创建包含六个undefined的数组,其他浏览器中会创建包含五个undefined的数组

由于IE的处理和其他浏览器不同,所以建议不要使用缺省值的方式来创建数组。

与对象一样,在使用数组字面量表示法时,也不会调用Array构造函数(Firefox3及之前版本除外)。

在读取和设置数组的值时,要使用方括号并提供相应的基于0的数字索引,例如:

var colors=["red","blue","green"];//创建一个有三个字符串的数组

var names=[];//创建一个空数组

alert(colors[0]);//显示第一项(索引小于数组中的项数,则返回对应项的值)

colors[2]="black";//修改第三项

colors[3]="brown";//新增第四项(索引超出现有项数,则数组会自动增加到该索引值加1的长度)

alert(colors.length);//3(初始情况下,该数组当中有三个值)

alert(names.length);//0

colors.length=2;//length属性并不是只读的,通过length属性,可以从数组的末尾移除项目

alert(colors[2]);//undifined

colors.length=4;//length属性并不是只读的,通过length属性,也可以向数组的末尾增添项目

alert(colors[3]);//undifined(新增的每一项都会去的undefined值)

colors[colors.length]="black";//在位置4添加一种颜色(数组最后一项的索引始终都是length-1,因此下一个新项的位置就是length)

colors[colors.length]="brown";//在位置5再添加一种颜色(每当在数组末尾添加一项后,其length属性就会自动更新以反映这一变化)

colors[99]="pink";//当把一个值放在超出当前数组大小的位置上时,数组就会重新计算其长度值

alert(colors.length);//100(长度等于最后一项的索引加1)

数组最多可以包含4294967295项数据,如果想添加的项数超过这个上限值就会发生异常,而创建一个初始大小与这个上限值接近的数组,则可能会导致运行时间超长的脚本错误。

确定某个对象是不是数组可以利用instanceof操作符来实现,例如:if(value instanceof Array){//某些操作}

但是由于instanceof操作符会假设只有一个全局执行环境,如果网页中包含多个框架,那么实际上就存在两个以上不同的全局执行环境,从而存在两个以上不同版本的Array构造函数。如果从一个框架向另外一个框架传入一个参数,那么传入的数组就与在第二个框架中原生创建的数组分别具有各自不同的构造函数。

为了解决这个问题ECMAScript5中新增了Array.isArray()方法,这个方法的目的就是最终确定某个值到底是不是数组,而不管它是在哪个全局执行环境中创建的,例如:if(Array.isArray(value)){//某些操作}

支持该方法的浏览器有IE9+、Firefox4+、Safari5+、Opera10.5+、Chrome。

每个对象都具有toLocaleString()、toString()、valueOf()方法,这三种方法默认都会以逗号分隔的字符串的形式返回数组项。

var colors=["red","blue","green"];//创建一个包含三个字符串的数组

alert(colors.toString());//red,blue,green(调用toString()方法会返回由数组中每个值的字符串形式拼接而成的以逗号隔开的字符串)

alert(colors.valueOf());//red,blue,green(调用valueOf()方法会返回数组)

alert(colors);//red,blue,green(将数组直接传递给alert(),由于alert()要接收字符串参数,所以会在后台调用toString()方法而得到与toString()相同的结果)

当调用toLocaleString()方法时,也会创建一个数组值的以逗号分隔的字符串,而与前两种方法不同的是,这一次为了取得每一项的值,调用的是每一项的toLocaleString()方法。

var person1={toLocaleString:function(){return "Nikolaos";},toString:function(){return "Nikolaos";}};

var person2={toLocaleString:function(){return "Grigorios";},toString:function(){return "Greg";}};

var people=[person1,person2];

alert(people);//Nikolaos,Greg

alert(people.toString());//Nikolaos,Greg

alert(people.toLocaleString());//Nikolaos,Gigorios

如果使用join()方法,可以用不同的分隔符来构建数组字符串,join()方法值接受一个用作分隔符的字符串作为参数,然后返回包含所有数组项的字符串。

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

alert(colors.join(","));//red,green,blue

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

如果不给join()方法传入任何值或者传入undefined,则使用逗号作为分隔符,IE7及更早版本会错误的使用字符串"undefined"作为分隔符。

如果数组中的某一项的值为null或者undefined,那么该值在以上四种方法的返回结果中以空字符串表示。

ECMAScript数组也提供了一种让数组的行为类似于其他数据结构的方法。

栈是一种LIFO(Last-In-First-Out,后进先出)的数据结构,而栈中项的插入(叫做推入)和移除(叫做弹出)值发生在栈的顶部。

ECMAScript中为数组提供了push()和pop()方法,用来实现类似于栈的行为。

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

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

var colors=new Array();//创建一个数组

var count=colors.push("red","green");//推入两项

alert(count);//2

count=colors.push("black");//推入另一项

alert(count);//3

var item=colors.pop();//取得最后一项

alert(item);//"black"

alert(colors.length);//2

队列是一种FIFO(First-In-First-Out,先进先出)的数据结构,队列在列表的末端添加项,从列表的前端移除项。

ECMAScript中提供了shift()方法,它能够移除数组中的第一项并返回该项,同时将数组的项目减1。

结合使用shift()和push()方法,可以像使用队列一样使用数组。

var colors=new Array();//创建一个数组

var count=colors.push("red","green","black");//推入三项

alert(count);//3

var item=colors.shift();//取得第一项

alert(item);//"red"

alert(colors.length);//2

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

结合使用unshift()和pop()方法,可以从相反的方向来模拟队列。

var colors=new Array();//创建一个数组

var count=colors.unshift("red","green");//推入两项

alert(count);//2

count=colors.unshift("black");//推入另一项

alert(count);//3

var item=colors.pop();//取得最后一项

alert(item);//"green"

alert(colors.length);//2

IE7及更早版本对JavaScript的实现中存在一个偏差,其中的unshift()方法总是返回undefined而不是数组的新长度,IE8在兼容模式下回返回正确的长度值。

ECMAScript中的数组有两个重新排序的方法:reverse()和sort(),他们返回的都是经过排序之后的数组。

reverse()方法会反转数组项的顺序,例如:var values=[1,2,3,4,5];values.reverse();alert(values);//5,4,3,2,1

sort()方法在默认情况下回按照升序排列数组项(最小的排在最前面,最大的排在最后面)。

为了实现排序,sort()方法会调用每个数组项的toString()转型方法,然后比较得到的字符串,以确定如何排序,例如:

var values=[0,1,5,10,15];values.sort();alert(values);//0,1,10,15,5(得到的是字符串比较的结果)

由于这种排序方式在很多情况下都不是最佳的,因此sort()方法还可以接收一个比较函数作为参数,以便我们制定哪个值位于哪个值前面,例如:

function compare(value1,value2){if(value1<value2){return -1;}else if(value1>value2){return 1;}else{retrun 0;}}

var values=[0,1,5,10,15];values.sort(compare);alert(values);//0,1,5,10,15

也可以通过反转比较函数中的返回值来实现降序排列。

对于数值类型或者其valueOf()方法会返回数值类型的对象类型,可以使用更简单的比较函数:function compare(value1,value2){return value2-value1;}

ECMAScript为操作应包含在数组中的项提供了很多方法。

concat()方法可以给予当前数组中的所有项创建一个新数组。

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

在没有给concat()方法传递参数的情况下,它只是赋值当前数组并返回副本。

如果传递给concat()方法的是一个或多个数组,则该方法会将这些数组的每一项都添加到结果数组中。

如果传递给concat()方法的是值而不是数组,这些值就会被简单的添加到数组末尾。

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

var colors2=colors.concat("yellow",["black","brown"]);

alert(colors);//red,green,blue

alert(colors2);//red,green,blue,yellow,black,brown

slice()方法能够基于当前数组中的一个或多个项创建一个新数组。

slice()方法可以接收一个或两个参数,即要返回项的起始位置和结束位置。

在只有一个参数的情况下,slice()方法返回从该参数指定位置开始到当前数组末尾的所有项。

如果有两个参数,slice()方法返回起始位置和结束位置之间但不包含结束位置所在项的所有项。

如果slice()方法的参数中有一个负数,则用数组长度加上该数来确定相应的位置。

如果传入的参数中结束位置小于起始位置,则返回空数组。

var colors=["red","green","blue","yellow","purple"];

var colors2=colors.slice(1);

var colors3=colors.slice(1,4);

var colors4=colors.slice(-2,-1);

var colors5=colors.slick(4,1);

alert(colors2);//green,blue,yellow,purple

alert(colors3);//green,blue,yellow

alert(colors4);//blue

alert(colors5);//null

splice()方法的主要用途是向数组的中部插入项,这种方法有如下三种规则:

(删除)如果给该方法传入两个参数,即要删除的第一项的位置和要删除的项数,则可以删除自指定位置起的任意数量的项;

(插入)如果给该方法传递三个或三个以上的参数,即起始位置、0(要删除的项数)和要插入的项,则可以向指定位置插入任意数量的项;

(替换)如果给该方法传递三个参数,即起始位置、要删除的项数和要插入的任意数量的项(删除数量和插入数量可以不相等),则可以向指定位置插入任意数量的项且删除任意数量的项。

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

var removed=colors.splice(0,1);//删除第一项

alert(colors);//green,blue

alert(removed);//red

removed=colors.splice(1,0,"yellow","orange");//从位置1开始插入两项

alert(colors);//green,yellow,orange,blue

alert(removed);//返回一个空数组

removed=colors.splice(1,1,"red","purple");//从位置1开始删除一项后插入两项

alert(colors);//green,red,purple,orange,blue

alert(removed);//yellow

ECMAScript5为数组实例添加了两个位置方法:indexOf()和lastIndexOf()。

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

其中,indexOf()方法从数组的开头开始向后查找,lastIndexOf()方法则从数组的末尾开始向前查找。

这两个方法都要返回要查找的项在数组中的位置,或者在没有找到的情况下回返回-1.

在比较第一个参数与数组中的每一项时,会使用全等操作符,且如果数组中有多个匹配项则只返回查找到的第一个位置。

支持这两种方法的浏览器有IE9+、Firefox2+、Safari3+、Opera9.5、Chrome。

ECMAScript5为数组定义了5个迭代方法,每个方法都接收两个参数:要在每一项上运行的函数和运行该函数的作用域对象(可选,影响this的值)。

传入这些方法中的函数会接收三个参数:数组项的值、该项在数组中的位置和数组对象本身。

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

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

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

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

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

var numbers=[1,2,3,4,5,4,3,2,1];

var everyResult=numbers.every(function(item,index,array){return (item>2);});

alert(everyResult);//false

var someResult=numbers.some(function(item,index,array){return (item>2);});

alert(someResult);//true

var filterResult=numbers.filter(function(item,index,array){return (item>2);});

alert(filterResult);//[3,4,5,4,3]

var mapResult=numbers.map(function(item,index,array){return item*2;});

alert(mapResult);//[2,4,6,8,10,8,6,4,2]

numbers.forEach(function(item,index,array){//执行某些操作});

//forEach()方法只是对数组中的每一项运行传入的函数,没有返回值,本质上与使用for循环迭代数组一样

支持这些方法的浏览器有IE9+、Firefox2+、Safari3+、Opera9.5、Chrome。

ECMAScript5还新增了两个归并数组的方法:reduce()和reduceRight()。

这两个方法都会迭代数组的所有项,然后构建一个最终返回的值。

其中,reduce()方法从数组的第一项开始逐个遍历到最后,reduceRight()则从数组的最后一项开始向前遍历到第一项。

这两个方法都接受两个参数:一个在每一项上调用的函数和作为归并基础的初始值(可选)。

传给这两个方法的函数接收四个参数:前一个值、当前值、项的索引和数组对象。

这个函数返回的值会作为第一个参数自动传给下一项,第一次迭代发生在数组的第二项上。

使用这两个方法当中的哪一个完全取决于从哪头开始遍历数组,初次之外他们完全相同。

var values=[1,2,3,4,5];

var sum=values.reduce(function(prev,cur,index,array){return prev+cur;});

alert(sum);//15

var sum2=values.reduceRight(function(prev,cur,index,array){return prev+cur;});

alert(sum2);//15

支持这两种方法的浏览器有IE9+、Firefox2+、Safari3+、Opera9.5、Chrome。

JS基础知识回顾:引用类型(一),布布扣,bubuko.com

时间: 2024-12-28 00:34:01

JS基础知识回顾:引用类型(一)的相关文章

JS基础知识回顾:引用类型(四)

每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法. 由于函数是对象,因此函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定. 函数的声明有以下三种形式: function sum(num1,num2){return num1+num2;}//利用函数声明语法定义 var sum=function(num1,num2){return num1+num2;}//利用函数表达式定义 var sum=new Function("num1","nu

JS基础知识回顾:引用类型(二)

ECMAScript中的Date类型是在早期Java中的java.util.Date类基础上构建的. 因此,Date类型使用自UTC(Coordinated Universal Time,国际协调时间)1970年1月1日午夜零点开始经过的毫秒数来保存日期. 在使用这种数据存储格式的条件下,Date类型保存的日期能够精确到1970年1月1日或之后的285616年. 要创建一个日期对象,使用new操作符和Date构造函数即可:var now=new Date(); 在调用Date构造函数而不传递参数

JS基础知识回顾:引用类型(三)

ECMAScript通过RegExp类型来支持正则表达式. 使用类似Perl的语法就可以创建一个正则表达式:var expression=/pattern/flags; 其中模式(pattern)部分可以是任何简单或复杂的正则表达式,可以包含字符类.限定符.分组.向前查找以及反向引用. 每个正则表达式都可以带有一个或多个标志(flags),用以标注正则表达式的行为. 正则表达式的匹配模式只是下列三个标志: g:表示全局(global)模式,即模式将被应用于所有字符串,而非在发现第一个匹配项时立即

JS基础知识回顾:引用类型(六)

ECMA-262对内置对象的定义是:由ECMAScript实现提供的.不依赖于宿主环境的对象,这些对象在ECMAScript程序执行之前就已经存在了. 开发人员不必显式的实例化内置对象,因为他们已经实例化了. 前面我们已经介绍了大多数内置对象,如Object.Array.String,ECMA-262还定义了两个单体内置对象:Global和Math. Global对象可以说是ECMAScript中最特别的一个对象了,因为不管你从什么角度上看,这个对象都是不存在的. 实际上并没有全局变量或全局属性

JS基础知识回顾:变量、作用域和内存问题

ECMAScript变量可能包含两种不同数据类型的值:基本类型值和引用类型值. 基本类型值指的是简单的数据段,而引用类型值指的是那些可能由多个值构成的对象. 引用类型的值是保存在内存中的对象,与其他语言不同,JavaScript不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间. 在操作对象时,实际上是在操作对象的引用而不是实际的对象. 在很多语言中,字符串以对象的形式来表示,因此被认为是引用类型的,ECMAScript放弃了这一传统. 定义基本类型值和引用类型值的方式是类似的:创建

JS基础知识回顾:在HTML中使用JavaScript

想HTML页面中插入JavaScript的主要方法就是使用<script>元素. HTML4.01当中为<script>元素定义了下列6个属性: language(已废弃):原来用于表示编写代码使用的脚本语言,如JavaScript.JavaScript1.2.VBScript等,由于大多数浏览器会忽略此属性,因此就没有必要再用了: type(可选):可以看成是language的替代属性,表示编写代码使用的脚本语言的内容类型,也被称作MIME类型,在未指定此属性的情况下会被默认为t

JS基础知识回顾:ECMAScript的语法(一)

任何语言的核心都必然会描述这门语言最基本的工作原理,而描述的内容通常都要涉及这门语言的语法.操作符.数据类型.内置功能等用于构建复杂解决方案的基本概念. ECMAScript中的一切变量.函数名.操作符都区分大小写. ECMAScript的标识符要符合下列规则:第一个字符必须是字母.下划线或美元符号:其他字符可以是字母.下划线.美元符号或数字. 标识符中的字母也可以包含扩展的ASCII或Unicode字母字符,但是并不推荐. 按照惯例,ECMAScript标识符采用驼峰大小写的格式来书写,尽管没

JS基础知识回顾:ECMAScript的语法(三)

ECMA-262描述了一组用于操作数据值的操作符,包括算术操作符.位操作符.关系操作符和相等操作符. ECMAScript操作符的与众不同之处在于,他们能够适用于很多值,例如字符串.数字值.布尔值.甚至是对象. 在将这些操作符应用于对象时,相应的操作符通常都会调用对象的valueOf()和(或)toString()方法,以便取得可以操作的值. 只能操作一个值的操作符叫做一元操作符. 递增和递减操作符直接借鉴自C,各有前置型和后置型两个版本:a++.++a.a--.--a 这四种操作符不仅适用于整

JS基础知识回顾:ECMAScript的语法(二)

ECMAScript中有五种简单数据类型(也称为基本数据类型):Undefined.Null.Boolean.Number.String ECMAScript还有一种复杂数据类型——Object,Object本质上是由一组无序的名值对组成的. ECMAScript不支持任何创建自定义类型的机制,而所有值最终都将是上述六种数据类型之一,由于ECMAScript的数据类型具有动态性,因此的确没有再定义其他数据类型的必要了. 监狱ECMAScript是松散类型的,因此需要有一种手段来检测给定变量的数据