JavaScript中的引用類型
引用類型的值是一個對象,一個引用類型相當於一個類,一個對象相當於一個實例。新對象用new操作符後跟構造函數來創造。
1.Object類型(Object類型本身不具備太多的功能,如Array這樣的引用類型本身就有很多功能,但是對存儲和傳輸數據時,或者自定義類時,比較方便)
有兩種創造方法:一是用new 構造函數方式;二是用字面量的方式創建
程序員通常會使用字面量方式來創建,因為字面量方式方便傳遞大量的數據,將含有大量數據的對象當做一個參數傳遞給函數。
2,Array類型(最常用的數據類型,ECMAScript的數組和其他語言不同的是,它可以用來保存任何類型的數據,而且大小是可以動態調整的)
有兩種創建方式:一是用new構造函數方式,二是數組字面量方式
例如:var colors=new Array(20); var colors=new Array(“Bule”,“red”);//var colors=["red","blue"];
Array的已有功能:可以通過length來對數組增刪改查;
確定某個對象是否是數組在一個網頁中使用instanceof 例如:if(value instanceof Array){} ;
但是如果網頁中有多個框架,就有兩個不同的執行環境,這樣就會存在不同的Array構造函數,如果從一個框架,往另一個框架中傳東西,那麽他們兩個是從屬於不同的構造函數的,為了 解決這個問題,現在就有另一個函數Array.isArray()函數來確定,它是否是一個數組;
轉換方法:toString(),toLocalString();valueof()方法。
toString會把每個數組數據項轉為字符串然後以逗號分隔拼接。調用valueOf的話其實返回的還是數組,toLocalString通常返回的值和前兩一樣。不同的是,toLocalString通常會對每個元素判斷,其定義的toLocalString方法,來返回值
以以上方法返回數組通常是以逗號隔開,使用join()方法,可以用不同分隔符來構建這個字符串,join()接收一個參數
例如:var colors=["red","green","blue"];
alert(colors.join(",")); //red,green,blue
alert("||");//red||green||blue
棧方法(先進先出):push()添加到數組的末尾和pop()從數組末尾移除最後一項。
隊列方法(先進後出):push()添加到數組末尾和shift()取得數組第一項。 反向操作隊列 unshift()添加第一項,pop()從數組末尾移除最後一項
重排序方法:reverse()方法和sort()方法;其中reverse()會翻轉數組中的數據項,僅僅是翻轉過來,沒有拍序。
而sort()方法會先調用toString方法,讓數組以數字,大寫字母,小寫字母來排序。因此在比較數字時,應該做個比較函數。sort(compare());
例如: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);
對於數據類型是數值的或者valueof()方法返回的數據類型是數值的對象類型,也樂意用
function compara(value1,value2){return value1-value2;}
操作方法(就是對已有的數據項進行操作的方法) :
concat()方法連接數組,添加一個數組的副本到另一個數組的末尾
slice()截取數組返回新數組,參數是起始位置和結束位置,如果參數是負數,則加上數組長度。
splice()方法,最強大的數組方法,主要用途是向數組中部插入項。
1,刪除任意數量的項,兩個參數,刪除第一項的位置和要刪除的項數例如:splice(0,2)刪除前兩項
2,插入指定位置任意數量的項。三個參數,起始,0(要刪除的項數),和要插入的項。例如:splice(2,0,“red”,“green”);從位置2來時插入兩個元素
3,替換,三個參數(其實和2是一樣的)例如:splice(2,1,“red”,“green”);刪除從2位置的項,刪除1項,並插入2個元素
位置方法:indexof()和lastindexof()兩個都是接收兩個參數,要查找的項和表示查找起點位置的索引;indexof()是從前往後找,lastindexof()是從後往前找,返回值為要查找的數據項在數組中 的位置。沒有找到則返回-1;例如:var numbers=[1,2,4,5,6,6,7]; alert(numbers.indexof(4));//2 alert(numbers.indexof(4,2));從第5開始查找,沒找到返回-1;
叠代方法:ECMAScript為數值定義了5中叠代,都是接收兩個參數:1,要在每一項上運行的函數function,(function會接收三個參數:數值項的值,該項在數組中的位置,和數組本身)2,運行該函 的作用域對象----影響this的值。
every():對數組中的每一項運行指定的function,每一項都返回true,則返回true;
filter():對數組中的每一項運行指定的function,返回運行function返回值為true的數組項組成的數組。
forEach():對數組中的每一項運行指定的function,沒有返回值
map():對數組中的每一項運行指定的function,返回每次調用function產生的結果值組成的數組
some():對數組中的每一項運行指定的function,有一項為true,則返回true
例如 :var nubmers=[1,2,3,4,5,6,5,4,3,2,1];
var everyResult=numbers.every(function(item,index,array){ reutrn (item>3); }); alert(evetyResult);
var mapResult=numbers.map(function(item,index,array){return(item*2)}); alert(mapResutl);
歸並方法:reduce()和reduceRight()兩個方法都會叠代數組,然後構建一個最終的返回值。都是接收兩個參數:1,作用在數組每一項上的函數function2,(可選)作為歸並的初始值
reduce()從數組的第一項開始,逐個遍歷到最後,reduceRight()方法從最後一項開始,
例如:var numbers=[1,2,3,4,5];
var sum=numbers.reduce(function(prev,cur,index,array){return pre+cur;}); alert(sum);//15;
其中function函數接收4個參數,前一個值,當前值,項的索引和數組本身。
3,Date類型
1, var now=new Date();//在不傳參的情況下,新創建的對象自動獲取當前日期和時間,如果想 根據特定的日期和時間創建日期對象,必須傳入表示該日期的毫秒數(既是從1970年算起)ECMAScript提供了兩種方法:Date.parase()方法和Date.UTC()方法
其中Date.parse()方法接收一個表示日期的字符串參數,然後根據這個字符串來轉化為相應的毫秒數。字符串格式有四種:如6/13/2004;january 12,2004等
例如:var nowDate=new Date(Date.parase("May 25 ,2004")); 這樣就得到了一個和“May 25 ,2004”相同的日期對象。
Date.UTC()方法同樣是返回毫秒數,但是其參數是年份,格式為(年月日),只有前兩個是必須的。
例如; var nowDate=new Date(Date.UTC(2004,12,23));
系統會根據本地時間,和系統設置的時間兩種來判斷,毫秒數使到什麽時間。
Date.now()方法,返回調用這個方法時的日期個時間; var sarteTime=Date.now(); doSomething(); var endTime=Date.now(); 這樣就可以知道運行的時間差了
2,繼承的方法
Date對象的toLocalString(),toString()和valueof()方法
toLocalString會按照與瀏覽器設置的地區想適應的格式返回日期和時間。
toStirng則通常返回帶有時區信息的時間。具體見:瀏覽器標準
valueof()根本不返回字符串,而是以毫秒表示,因此可以用大小比較符來比較兩個時間。
例如: var date1=new Date(2007,0,1); var date2=newDate(2007,1,2);
3,日期的格式化輸出(有一些函數專門將,日期轉化為某種格式來展現)
如toDateString();toTimeString();等等具體見101頁
4,日期/時間組件方法(都是直接取得和設置日期值中特定的方法。)
如:getTime()返回時間的毫秒數和valueof()一樣;getMonth()返回日期中的月份;getHours()返回日期中的小時,等等見102頁
4,RegExp類型
ECMAScript用RegExp類型來支持正則表達式。 var expression=/pattern/flags;
1,正則表達式中有三種匹配模式,對應3個標誌:g(全局模式),應用於所有字符串;i(不區分大小寫模式);m(多行模式)既是在達到一行文本末尾時,還會繼續查找下一行
例如:var pattern1=/at/g; 匹配字符串中所有的“at”
var pattern2=/[bc]at/i; 匹配第一個bat或者cat,並不區分大小寫
var pattern3=/.at/gi; 匹配所有以at結尾的字符串,並不區分大小寫
2,如果([ { \$ |}])作為字符出現在匹配模式中,必須用"\"來進行轉義。例如:var pattern=/\[bc\]at/ ;和 “\\[bc\\]at”; 其中對"\"字符進行了轉義;
3,有兩種創建正則對象的方法,一種是字面量方式,一種是用new RegExp()構造函數:構造函數要接受兩個參數,一個是匹配模式字符串,一個是標識字符
如果是字面量的話,\*****\中間是沒有轉義字符“\”的,而是他本身的字符;轉義字符要出現在構造函數中
4,RegExp實例屬性:例如:var pattern=/[ba]t/gi; alert(pattern.global); //true
global:布爾值,標識是否設置了全局模式
ignoreCase:布爾值,標識是否設置了i標誌
lastIndex:整數,表示開始搜索下一個匹配項的字符位置。從0算起
multiline:布爾值標識是否設置了m標識。
source:正則表達的字符串標識,
5,RegExp實例的方法
1, RegExp對象的主要方法是exec();主要功能是捕獲組
接收一個參數,既是應用模式的字符串,然後返回包含第一個匹配項信息的數組,沒有匹配到返回null;然後返回的這個數組包含兩個新屬性;index和input
index標識匹配項在字符串中的位置,而input標識應用正則表達式的字符串
例如:var text=“ mom and dad and baby”;
var pattern=/mom(and dad(and baby)?)?/gi/; //這個正則中包含了兩個捕獲組 先從最內部的捕獲組開始
var matches=pattern.exec(text); //此時matches是一個包含信息 的數組
alert(matches.index); //0
alert(matches.input); //"mom and dad and baby" //q去除捕獲組後的正常的正則要匹配的數組
alert(matches[0]);//"mom and dad and baby"
alert(matches[1]); //"and dad and baby"
alert(matches[2]);//"and baby"
2,test()方法,接收一個參數,模式與參數匹配返回true,不匹配返回false
例如:var text=“000-00-000”;
var pattern =/\d(3)-\d(2)-\d(4)/;
if(pattern.test(text)){******}
3,toLocalString和toStirng都會返回其字面量字符串
6,RegExp構造函數的屬性(有長屬性名和短屬性名)短屬性名必須用方括號括起來:input(最近一次要匹配的字符串) lastMatch(最近一次的匹配項) 等等 見於108頁
5,Function類型(每個函數都是Function的實例)
1,三種實例方式:1,function sum(num1,num2){ ****} 2,var sum=function(num1,num2){*****};(末尾要加分號,和其他變量一樣) 3,var sum=new Function(“”“”“”“”“”“”“”“”“”“”)(不推薦)
JavaScript中函數沒有重載:將函數名想象成指針,根據引用類型 的斷線規則,可以清楚的看到,創建第二個函數時,會覆蓋一個函數的內容(既是堆中的實際內容會被覆蓋)
2,函數聲明和函數表達式
例如:alert(sum(10,10)); function sum(num1,num2){*******} //這是正確的
alert(sum(10,10)); var sum=function(num1,num2){*********}//這是錯誤的,
原因是,JavaScript中會將函數的解析優先級提高在語句之前,而通過變量定義的函數,並不會提高優先級 ;處了這點之外,其他均相同
3,作為值的函數(JavaScript中函數名本身就是變量,所以可以當做值來使用)
作為值很多時候是作為一個函數的參數來傳遞,JavaScript中,通常是以第一個參數傳遞函數名,第二個參數為一個作為參數的函數的參數
例如:function callSomeFunction (somFunction,someArgument){
return someFunction(someArgument);}
someArgument 為someFunction的參數;
當然 也可以從一個函數中返回另一個函數,這也是非常有用的技術; 例如:sort()排序的比較
function creatComparaFunction(property){
return function (object1,object2){
var name1=object1[property];
var name2=object[property];
if(name1>name2){return 1;}else if(name1<name2){return -1}else{return 0}} }
4,函數的內部屬性(arguments和this兩個特殊的對象)
1,arguments主要是為了保持參數,但是其有一個屬性callee,這個屬性是一個指針,用處理遞歸算法。arguments.callee 表示指向自己
2,this對象,在不同的執行環境中代表當前的環境對象,全局中是window對象; 在函數中代表是調用函數的對象
function setColors(){alert(this.colors;)} //誰調用這個函數,this就代表誰,代表那個對象,將這個對象的colors打印出來
5,函數的屬性和方法
ECMAScript中的函數是對象,因此函數也有屬性和方法
1,每個函數包括兩個屬性:length和prototype;
其中length表示希望接收到命名參數的個數,既是函數參數的個數
prototype屬性保存它們實例方法的真正所在,也就是說toString(),valueof()等方法實際存在pr,函數體內的this對象的值。
2,包括兩個方法call()和apply()方法;用途在於在某個作用域內調用函數,下面的例子就是在 callsum1和callsum2函數中調用了sum函數
1,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)); //這個例子中傳入this做完this值,因為在全局中,this代表了window
2,call()方法和apply()方法的作用相同,僅有的區別在參數的傳遞上。call()方法,第一個參數是this沒有變化,其余的參數都是直接傳遞給函數。必須逐個列舉
return sum.call(this,num1,num2);
3,它們真正的強大之處在於擴充函數運行的作用域
例如 window.color="red"; var o={color="blue"}; function sayColor(){alert(this.color;)} saycolor();//red sayColor(this); //red sayColor(o);//blue
相當於規定了函數運行的作用域。
3,ECMAScript函數還定義了一個bind()方法,這個方法會創建一個函數的實例。其this的值會被綁定到bind()函數的值
window.color="red"; var o={color="blue"}; function sayColor(){alert(this.color;)} var ObjectSayColor=sayColor.bind(o); ObjectSayColor(); //blue
相當於規定了函數運行的作用域和上面的call()函數相似。
JavaScript中的引用類型