JavaScript中引用类型详解

引用类型

引用类型的值是引用类型的一个实例,在ECMAScript中,引用类型是一种数据结构,用于将数据和功能组织在一起,他们描述的是一类对象所具有的属性和方法。

Object类型

大多数引用类型值都是Object类型的实例,Object也是ECMAScript中使用最多的一个类型。创建Object实例的方式有两种:
第一种是使用new操作符跟Object构造函数。例如:

var person = new Object();
person.say = "hello";

第二种方式是使用对象字面量表示法。例如:

var person = {
    say : "hello";
};

另外在使用对象字面量语法时,如果留空花括号,则可以定义只包含默认属性和方法的对象。例如:

var person = {};//与new Object相同
person.say = "hello";

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

alert(person["say"]); //"hello"
Array类型

ECMAScript数组与其他语言中数组都是数据的有序数组,ECMAScript数组的每一项可以保存任何类型的数据,而且ECMAScript数组的大小时可以动态调整的,可以随着数据的添加自动增长以容纳新的数据。创建数组的基本方式有两种:
第一种是使用Array构造函数,例如:

var colors = new Array();

也可以给构造函数传递数量,创建length长度的数组。例如:

var colors = new Array(20);

也可以向数组构造函数中传递数组中包含的项,例如:

var colors = new Array("red","blue","green");

在使用Array构造函数时也可以省略new 操作符。例如:

var colors = Array();

第二种是使用数组字面量表示法。例如:

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

数组中的length属性不是只读的,可以通过设置这个属性,从数组的末尾移除或向数组中添加新项。
ECMAScript新增了Array.isArray()方法,确定某个值到底是不是数组,而不管它是在哪个全局执行环境中创建的。例如:

if(Array.isArray(value)){
    //do something
}
转换方法

所有对象都具有toLocaleString()、toSting()和valueOf()方法,调用数组的toString()方法会返回由数组中每个值的字符串形式拼接成的一个以逗号分隔的字符串,而调用valueof()返回的还是数组。例如:

var colors = ["red","blue","green"];
alert(colors.toString());           //red,blue,green;
alert(colors.valueOf());            //red,blue,green;       

默认情况下都会以逗号分割字符串的形式返回数组项,如果使用join()方法,则可以使用不同的分隔符来构建这个字符串,jion()方法只接收一个参数,即用作分隔符的字符串,然后返回包含所有数组项的字符串。例如:

var colors = ["red","green","blue"];
alert(colors.join("||"));           //red||green||blue
栈方法

ECMAScript为数组专门提供了push()、pop()方法,以便实现类似栈(后进先出)的行为。
push():接收任意数量的参数,把他们逐个添加到数组末尾,并返回修改后数组的长度。
pop():则从数组末尾移除最后一项,减少数组的length值,然后返回移除的项。例如:

var colors = new Array();
var count = colors.push("red","green");
alert(count);                          //2
var item = colors.pop();
alert(item);                            //green
队列方法

队列(先进先出)在列表的末端添加项,在列表的前端移除项。
shift():移除数组中的第一项并返回该项,同时将数组长度减1。例如:

var colors = ["red","green","blue"];
var item = colors.shift();
alert(item);              //"red";
alert(colors.length);     //2

unshift():在数组前端添加任意个项并返回新数组的长度。例如:

var colors = ["red","green","blue"];
var count = colors.unshift("black","orange");
alert(count);                       //5
重排序方法

数组中存在两个可以直接用来可以重排序的方法:reverse()、sort()。
sort()方法比较的是字符串。
排序举例:

function compare(value1,value2){
    return value2 - value1;
}
var values = [0,1,5,10,15];
values.sort(compare);
alert(values);            //15,10,5,1,0
操作方法

concat():创建当前数组的一个副本,然后将接收到的参数添加到这个副本的末尾,最后返回新构建的数组。例如:

var colors = ["red","green","blue"];
var colors2 = colors.concat("yellow",["black","brown"]);
alert(colors2);                        //red,green,blue,yellow,black,brown

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

var colors1 = ["red","green","blue","yellow","purple"];
var colors2 = colors1.slice(1);
var colors3 = colors1.slice(1,4);
alert(colors2);             //green,blue,yellow,purple
alert(colors3);             //green,blue,yellow

splice():可以实现删除、插入、替换,返回一个数组。
删除:提供2个参数,要删除的第一项的位置和要删除的项数;
插入:提供3个参数,起始位置,0,要插入的项;
替换:提供3个参数,起始位置,要删除的项数,要插入任意位置的项。例如:

var colors = ["red","green""blue"];
var remove = colors.splice(0,1);
alert(colors);                //green,blue
alert(remove);                //red

remove = colors.splice(1,0,"yellow","orange");
alert(colors);                //green,yellow,orange,blue

remove = colors.splice(1,1,"red","purple");
alert(colors);                 //green,red,purple,orange,blue
位置方法

ECMAScript5为数组实例添加了两个位置方法:indexOf()和lastIndexOf(),这两个方法都接收两个参数:要查找的项和(可选)表示查找起始位置的索引。两个方法都返回要查找的项在数组中的位置,在没有找到的情况下返回-1。要查找的项和数组中的每一项比较时会使用全等操作符。例如:

var numbers = [1,2,3,4,5,4,3,2,1];
alert(numbers.indexOf(4));        //3
alert(numbers.lastIndexOf(4));    //5

alert(numbers.indexOf(4,4));      //5
alert(numbers.lastIndexOf(4,4));  //3
迭代方法

every():对数组中的每一项运行给定函数,如果函数对每一项都返回true,则返回true;
filter():对数组中的每一项运行给定函数,返回该函数会返回true的项组成的数组;
forEach():对数组中的每一项运行给定函数,无返回值;
map():对数组中的每一项运行给定函数,返回函数每次调用的结果组成的数组;
some():对数组中的每一项运行给定函数,如果该函数对任意一项返回true,则返回true。

归并方法

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
Date类型

Date类型使用自UTC1970年1月1日零时开始经过的毫秒数来保存日期。要创建一个日期对象,使用new操作符和Date构造函数即可,例如:

var date = new Date();
RegExp类型

ECMASccript通过RegExp类型来支持正则表达式。
创建正则表达式方法一:

var expression = /pattern/flags;

其中模式(pattern)部分可以是任何简单或复杂的正则表达式,可以包含字符类,限定类,分组,向前查找以及反向引用。每个正则表达式都带有一个或多个标志(flags),用以标明正则表达式的行为。正则表达式的匹配模式支持3个标志:
g:表示全局模式,即模式应用于所有字符串;
i:表示不区分大小写模式,即在确定匹配项时忽略模式与字符串的大小写;
m:表示多行模式。
一个正则表达式就是一个模式与3个标志体的组合体。
创建正则表达式方法二:

var regExp = new RegExp(pattern,attributes);
Function类型

每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法,由于函数时对象,因此函数名实际上是一个指向函数对象的指针,不会与某个函数绑定。任何函数在任何时候都可以通过return语句后跟要返回的值来实现返回值,位于return之后的代码都永远不会执行。定义函数有三种方式:
方式一,使用函数声明语法定义:

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

方式二,使用函数表达式定义:

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

方式三,使用function构造函数定义,function构造函数可以接收任意数量的参数,但最后一个参数始终是函数体:

var sum = new Function("num1","num2","return num1+num2");

使用不带圆括号的函数名是访问函数指针,而非调用函数

没有重载

ECMAScript中没有重载,当声明了两个同名函数,后面的函数会覆盖前面的函数。

函数声明和函数表达式

解析器在向执行环境中加载数据时,会率先读取函数声明,并使其在执行任何代码之前可用;至于函数表达式,则必须等到解析器执行到它所在的代码行,才会被解释执行。

作为值的函数

不仅可以像传递参数一样把一个函数传递给另一个函数,而且可以将一个函数作为另一个函数的结果返回。

function callSomeFunction(someFunction, someArgument){
    return someFunction(someArgument);
}
函数的内部属性

在函数内部,有两个特殊的对象:arguments和this。
arguments是一个类数组对象,包含着传入函数中的所有参数,这个对象还有一个callee属性,该属性是一个指针,指向拥有该arguments的函数。例如,阶乘的经典案例:

function factorial(num){
    if(num <= 1){
        return 1;
    }else{
        return num*arguments.callee(num-1);
    }
}

this 引用的是函数执行的环境对象。,当在网页的全局作用域中调用函数时,this对象引用的就是window。例如:

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

另一个函数对象的属性caller,这个属性保存着调用当前函数的函数引用,如果在全局作用域中调用当前函数,它的值为null。例如:

function outer(){
    inner();
}
function inner(){
    alert(inner.caller);
}
outer();

以上代码会导致警告框中显示outer()函数的源代码。

函数的属性和方法

每个函数包含两个属性:length和prototype。
length:表示函数希望接受的命名参数的个数。
对于ECMAScript中的引用类型而言,prototype是保存他们所有实例的真正所在。诸如toString()和valueOf()等方法实际上都保存在prototype名下,通过各自对象的实例访问。
每个函数都有两个非继承而来的方法:apply()和call()。这两个方法都在特定的作用域中调用函数,等于设置函数体内this值的对象。
apply()方法接收两个参数:一个是运行的作用域,一个是参数数组,其中第二个参数可以是Array()的实例,也可以是arguments()对象。例如:

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));                //20
alert(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

事实上,传递参数并非apply()和call()真正的用武之地,他们真正强大的地方是能够扩充函数赖以运行的作用域。例如:

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

ECMAScript5还定义了一个方法:bind(),这个方法会创建一个函数的实例,其this值会被绑定到传给bind()函数的值。例如:

window.color = "red";
var o = {color:"blue"};
function sayColor(){
    alert(this.color);
}
var objectSayColor = sayColor.bind(o);
objectSayColor();                        //"blue"
基本包装类型

为了便于操作基本类型值,ECMAScript还提供了3个特殊的引用类型:Boolean、Number、String。这些类型与其他引用类型相似,但同时具有与各自基本类型相应的特殊行为。
引用类型与基本包装类型的主要区别在于对象的生存期,使用new操作符创建的引用类型的实例,在执行流离开当前作用域之前都一直保存在内存中;而自动创建的基本包装类型的对象,则只存在于一行代码额执行瞬间,然后立即被销毁,这意味着我们不能在运行时为基本类型值添加属性和方法。

Boolean类型

Boolean是与布尔值对应的引用类型,创建Boolean的对象:

var booleanObject = new Boolean(true);

Boolean对象常常会造成人们的误解,例如:

var falseObject = new Boolean(false);
var result = falseObject && true;
alert(result);                       //true

布尔表达式中的所有对象都会被转换为true,因此falseObject对象在布尔表达式中代表的是true。

Number类型

Number是与数字值对应的引用类型,要创建Number对象,可以在调用Number构造函数时向其中传递相应的数值。例如:

var numberObject = new Number(10);
String类型

String类型是字符串对象包装类型,可以使用String构造函数来创建,例如:

var stringObject = new String("hello world");

String类型提供了很多方法,用于辅助完成对ECMAScript中字符串的解析和操作。

  • 字符方法:charAt()和charCodeAt(),charAt()以单字符字符串的形式返回给定位置的那个字符,charCodeAt()返回给定位置的字符编码。例如:
var string = "hello world";
alert(string.charAt(1));   //"e"
alert(string.charCodeAt(1));//"101" 

字符编码:A 65;a 97;

  • 字符串操作方法
    concat()用于将一个或多个字符串拼接起来,返回拼接得到的新字符串,例如:
var string = "hello";
var result = string.concat("world");
alert(result);                     //"helloworld"

虽然concat()时专门用来拼接字符串的方法,但实践中使用最多的还是加号操作符(+),而且加号操作符在多数情况下都比使用concat()方法简单易行。
ECMAScript还提供了3个基于子字符串创建新字符串的方法:slice()、substr()、substring(),这3个方法都会返回操作字符串的一个新字符串。例如:

var string = "hello world";

alert(string.slice(3));    //"lo world"
alert(string.slice(3,7));  //"lo w"

alert(string.substring(3)); //"lo world"
alert(string.substring(3,7)); //"lo w"

alert(string.substr(3));        //"lo world"
alert(string.substr(3,7));      //"lo worl"
  • 字符串位置方法
    indexOf()和lastIndexOf(),这两个方法都是从一个字符串中搜索给定的子字符串,然后返回子字符串的位置。例如:
var string = "hello world";
alert(string.indexOf("0"));   //4
alert(string.lastIndexOf("o"));//7
  • trim()方法会创建一个字符串的副本,删除前置和后缀所有的空格,然后返回结果。例如:
var string = "  hello world  ";
alert(string.trim());         //"hello world"
  • 字符串大小写转换方法
    toLowerCase()和toUpperase()时两个经典的方法。例如:
var string = "hello world";
alert(string.toUpperCase());       //"HELLO WORLD"
alert(string.toLowerCase());       //"hello world"
  • 字符串的模式匹配方法
    match()方法只接受一个参数,要么是一个正则表达式,要么是一个RegExp对象,返回一个数组。例如:
var text = "cat,bat,sat,fat";
var pattern = /.at/;
var matches = text.match(pattern);
alert(matches[0]);                //"cat"

search()方法从字符串开头向后查找,返回字符串中第一个匹配项的索引,如果没有找到匹配项则返回-1。例如:

var text = "cat,bat,sat,fat";
var pos = text.search(/at/);
alert(pos);                   //1

replace()替换子字符串,例如:

var text = "cat,bat,sat,fat";
var result = text.replace("at","ond");
alert(result);                        //"cond,bat,sat,fat"

result = text.replace(/at/g,"ond");
alert(result);                         //"cond,bond,aond,fond"

split()方法可以基于指定的分隔符将一个字符串分割成多个子字符串,并将结果放到一个数组中,例如:

var colorText = "red,blue,green,yellow";
var color1 = colorText.split(",");      //["red","blue","green","yellow"]
var color2 = colorText.split(",",2);    //["red","blue"]
  • localeCompare()方法
    localeCompare()方法用于比较两个字符串,例如:
var stringValue = "yellow";
alert(stringValue.localeCompare("brick"));    //1
alert(stringValue.localeCompare("yellow"));    //0
alert(stringValue.localeComprae("zoo"));       //-1
  • fromCharCode()
    formCharCode()方法接收一个或多个字符编码,然后将他们转换为一个字符串。例如:
alert(String. formCharCode(104,101,108,108,111));  //"hello"
单体内置对象

内置对象:开发人员不必显示地实例化内置对象,因为他们已经实例化了。
Global对象:所有在全局作用域中定义的属性和函数。
Math对象:提供计算功能和辅助完成这些计算的属性和方法。
min()和max()用于确定一组数值中的最小值和最大值。例如:

var max = Math.max(3,54,32,16);
alert(max);                   //54
var min = Math.min(3,54,32,16);
alert(min);                    //3

Math.ceil()执行向上舍入;
Math.floor()执行向下舍入;
Math.round()执行标准舍入。
random()方法返回大于等于0小于1的一个随机数,例如:
介于2-10之间(包括2和10)的一个数值

function selectFrom(lowerValue,upperValue){
    var choices = upperValue - lowerValue;
    return Math.floor(Math.random()*choices + lowerValue);
}
var num = selectFrom(2,10);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值