RegExp類型
ECMAScript通過RegExp類型支持正則表達(dá)式。
var expression = /pattern / flags;
pattern 模式就是正則表達(dá)式。
一個正則表達(dá)式是一個模式與3個標(biāo)準(zhǔn)的組合體(i、g、m)
m多行模式,即到達(dá)一行文本末時還會繼續(xù)還會繼續(xù)查找下一行中是否存在與與模式匹配的項。
每個元字符在正則表達(dá)式中都有一種或多種特殊用途,因此如果想要匹配字符串中包含的這些字符,就必須進(jìn)行轉(zhuǎn)義。
var pattern1 = /[bc]at/i;//匹配第一個"bat"或"cat",不區(qū)分大小寫
var pattern2 = /\[bc\]at/i;//匹配第一個"[bc]at",不區(qū)分大小寫
var pattern1 =/.at/gi;//匹配以“at”結(jié)尾的3個字符的組合,不區(qū)分大小寫
var pattern2=/\.at/gi;//匹配所有".at",不區(qū)分大小寫
另外一種是構(gòu)造函數(shù),接受2個參數(shù)
var pattern1 = /[bc]at/i;
var pattern2 = new RegExp("[bc]at","i");
RegExp 實例方法
RegExp對象的主要方法是exec(),該方法是專門為捕獲組設(shè)計的。接受一個參數(shù),即要應(yīng)用模式的字符串,返回包含第一個匹配信息的數(shù)組;或者在沒有匹配項的情況下返回null。返回的數(shù)組是Array的實例,它包含2個屬性:index(匹配項在字符串中的位置)和input(表示應(yīng)用正則表達(dá)式的字符串)。在數(shù)組中,第一項是與整個模式匹配的字符串,其他項是與模式中的捕獲組匹配的字符串(如果沒有捕獲組,該數(shù)組只包含一項)
捕獲組是指正則表達(dá)式中子表達(dá)式匹配的內(nèi)容,保存到內(nèi)存中以數(shù)字編號或顯式命名的組里,方便后面引用。
var text = "mom and dad and baby";
var pattern = /mom( and dad ( and baby )?)?/gi;
var matches = pattern.exec(text);
alert(matches.index);//0
alert(matches.input);//"mom and dad and baby"
alert(matches[0]);//"mom and dad and baby"
alert(matches[1]); //"and dad and baby"
alert(matches[2]);//"and baby"
對于exec()方法而言,即使在模式中設(shè)置了全局標(biāo)志,每次也只會返回一個匹配項,不設(shè)置全局標(biāo)志,在同一個字符串上多次調(diào)用exec()每次始終返回第一個匹配項的信息。設(shè)置全局標(biāo)志,每次調(diào)用exec()都會在字符串中繼續(xù)查找新匹配項
var text = "car,bat,sat,fat";
var pattern1 =/.at/;
var matches = pattern1.exec(text);
alert(matches.index);//0
alert(matches[0]);//cat
alert(pattern1.lastIndex);//0
matches = pattern1.exec(text);
alert(matches.index);//0
alert(matches[0];//cat
alert(matches.lastIndex);//0
var pattern2=/.at/g;
var matches = pattern2.exec(text);
alert(matches.index);//0
alert(matches[0]);//cat
alert(pattern2.lastIndex);//3
matches = pattern.exec(text);
alert(matches.index);//5
alert(matches[0]);//bat
alert(matches.lastIndex);//8
另外一個方法test()
它接受一個字符串參數(shù),在模式與該參數(shù)匹配的情況下返回true.否則返回false。
在只想知道目標(biāo)字符串與某個模式是否匹配,但不需要知道其文本內(nèi)容的情況下,這個方法非常方便。
var text = "000-00-0000";
var pattern = /\d{3}-\d{2}-\d{4}/;
if (pattern.test(text)){
alert("The pattern was matched.");
}
構(gòu)造函數(shù)的屬性
RegExp構(gòu)造函數(shù)包含一些屬性,這些屬性適用于作用域中的所有正則表達(dá)式,并且基于所執(zhí)行的最近一次正則表達(dá)式操作而變化。
如果用短屬性名,由于大部分不是有效的ECMAScript標(biāo)識符,就必須通過方括號來訪問。
var text = "this has been a short summer";
var pattern = /(.)hort/g;
if (pattern.test(text)){
alert(RegExp.input);//this has been a short summer
alert(RegExp.$_);
alert(RegExp.leftContext);//this has been a
alert(RegExp["$`"]);
alert(RegExp.rightContext);//summer
alert(RegExp["$' "])
alert(RegExp.lastMatch);//short
alert(RegExp["$&"])
alert(RegExp.lastParen);//s lastParen=最近一次匹配的捕獲組
alert(RegExp["$+"])
alert(RegExp.multiline);//false
alert(RegExp["$*"])
多達(dá)9個用于存儲捕獲組的構(gòu)造函數(shù)屬性。RegExp.$1、RegExp.$2.....分別存儲第一個、第二、第九個匹配的捕獲組,在調(diào)用exec() 或test() 方法時,這些屬性會被自動填充。
var text = "this has been a short summer";
var pattern = /(..)or(.)/g;
if(pattern.test(text)){
alert(RegExp.$1);//sh
alert(RegExp.$2);//t
}
參考:http://www.cnblogs.com/snandy/p/3662423.html
function 類型
每個函數(shù)都是function類型的實例,具有屬性和方法。
函數(shù)是對象,因此函數(shù)名是一個指向函數(shù)對象的指針,不會與某個函數(shù)綁定。
function sum(num1,num2){
return num1 + num2;
}//函數(shù)聲明語法
var sum =function(num1,num2){
return num1 + num2;
}//將變量sum初始化為一個函數(shù),function關(guān)鍵詞后面沒有函數(shù)名,因為在使用函數(shù)表達(dá)式定義函數(shù)時,沒有必要使用函數(shù)名-通過變量sum即可引用函數(shù)。
var sum = new Function("num1","num2","return num1+ num2");
//function構(gòu)造函數(shù),接受任意數(shù)量的參數(shù),最后一個參數(shù)為函數(shù)體。
//不推薦這種方式,因為會導(dǎo)致解析2次代碼(第一次解析常規(guī)ECMAScript代碼,第二次是解析傳入構(gòu)造函數(shù)中的字符串),從而影響性能
//不過這種方式對于理解函數(shù)是對象,函數(shù)名是指針的概念是非常直觀的。
函數(shù)聲明與函數(shù)表達(dá)式
alert(sum(10,10));
function sum(num1,num2){
return num1+num2;
}
以上函數(shù)正常運(yùn)行。因為在代碼開始執(zhí)行之前,解析器就已經(jīng)通過一個名為函數(shù)聲明提升(function declaration hoisting)的過程,讀取并將函數(shù)聲明添加執(zhí)行環(huán)境中。對代碼求值時,JavaScript引擎在第一遍會聲明函數(shù)并將它們放到源代碼樹的頂部。但改為函數(shù)表達(dá)式就會導(dǎo)致錯誤。
alert(sum(10,10));
var sum =function (num1,num2){
return num1+num2;
}
作為值的函數(shù)
function callSomeFunction(someFunction,someArgument){
return someFunction(someArgument);
}
function add10(num){
return num+10;
}
var result1 = callSomeFunction(add10,10);
alert(result1);//20
function getGreeting(name){
return "Hello, " +name;
}
var result2 = callSomeFunction(getGreeting,"Nicholas");
alert(result2); //"Hello,Nicholas"
函數(shù)可以作為一個參數(shù)傳遞給另一個函數(shù),也可以作為一個函數(shù)的結(jié)果返回。上例中,第一個參數(shù)someFunction是一個函數(shù),第二個參數(shù)someArgument是傳遞給該函數(shù)的一個值。
function createComparisonFunction(propertyName){
return function(object1,object2){
var value1 = object1[propertyName];
var value2 = object2[propertyName];
if (value1 <value2){
return -1;
} else if (value1 >value2) {
return 1;
} else {
return 0;
}
};
}
var data = [{name:"Zachary",age:28},{name: "Nicholas", age:29}];
data.sort(createComparisonFunction("name"));
alert(data[0].name);//Nicholas
data.sort(createComparisonFunction("age"));
alert(data[0].name);//Zachary;
一個對象數(shù)組,根據(jù)某個屬性對數(shù)組進(jìn)行排序,但需要一種方式指明按照哪個屬性來排序,為此,需要定義一個函數(shù),接受一個屬性名,然后根據(jù)這個屬性名來創(chuàng)建一個比較函數(shù)。
函數(shù)內(nèi)部屬性
函數(shù)內(nèi)部有2個特殊對象,arguments和this.
arguments是一個類數(shù)組對象,包含傳入函數(shù)中的所有參數(shù),主要用于保存函數(shù)參數(shù),這個對象有一個callee屬性,是一個指針,指向擁有這個arguments對象的函數(shù)。
耦合是指兩個或兩個以上的體系或兩種運(yùn)動形式間通過相互作用而彼此影響以至聯(lián)合起來的現(xiàn)象。 解耦就是用數(shù)學(xué)方法將兩種運(yùn)動分離開來處理問題,常用解耦方法就是忽略或簡化對所研究問題影響較小的一種運(yùn)動,只分析主要的運(yùn)動。
function factorial(num){//定義階乘函數(shù)一般都要用到遞歸算法,如果函數(shù)名稱不會變化的話,這樣定義沒有問題。但這個函數(shù)的執(zhí)行與函數(shù)名factorial僅僅耦合在了一起。為了消除耦合,可以使用arguments.callee.
if (num<=1){
return 1;
} else{
return num * factorial(num-1);
}
}
function factorial(num){
if (num<=1){
return 1;
} else {
return num *arguments.callee(num-1);
}
}//這個函數(shù)中,沒有引用函數(shù)名factorial。
var trueFactorial =factorial;
factorial = function() {
return 0;
};
alert(trueFactorial(5));//120
alert(factorial(5));//0
遞歸算法,其實說白了,就是程序的自身調(diào)用。
遞歸算法所體現(xiàn)的“重復(fù)”一般有三個要求:
(1) 是每次調(diào)用在規(guī)模上都有所縮?。ㄍǔJ菧p半);
(2) 是相鄰兩次重復(fù)之間有緊密的聯(lián)系,前一次要為后一次做準(zhǔn)備(通常前一次的輸出就作為后一次的輸入);
(3) 是在問題的規(guī)模極小時必須用直接給出解答而不再進(jìn)行遞歸調(diào)用,因而每次遞歸調(diào)用都是有條件的(以規(guī)模未達(dá)到直接解答的大小為條件),無條件遞歸調(diào)用將會成為死循環(huán)而不能正常結(jié)束。
函數(shù)調(diào)用只有一種形式:func.call(context, p1, p2)
http://stackoverflow.com/questions/7056925/how-does-array-prototype-slice-call-work
另一個函數(shù)對象的屬性是caller ,保存著調(diào)用當(dāng)前函數(shù)的函數(shù)的引用。
function outer(){
inner();
}
function inner(){
alert(inner.caller);
}
outer();
因為outer()調(diào)用了inner(),所以inner.caller指向了outer()。為了實現(xiàn)更松散的耦合,可以把inner.caller改為arguments.callee.caller
函數(shù)的屬性和方法
函數(shù)是對象,所以也有屬性和方法。2個屬性:length表示接受的命名參數(shù)的個數(shù)。另一個是this,https://zhuanlan.zhihu.com/p/23804247
每個函數(shù)包含2個非繼承而來的方法:apply()和call(),這2個方法的用途是在特定的作用域中調(diào)用函數(shù),實際上等于設(shè)置函數(shù)體內(nèi)this對象的數(shù)值。apply()方法接收2個參數(shù),一個是在其中運(yùn)行函數(shù)的作用域,另一個是參數(shù)數(shù)組(可以是參數(shù)數(shù)組,也可以是 Array 的實例)。call()的不同之處是第二個參數(shù)是直接的參數(shù),逐個列舉出來。(this,num1,num2)
function sum(num1,num2){
return num1 + num2;
}
function callSum1(num1,num2){
return sum.apply(this,arguments);//傳入 arguments對象
}
function callSum2(num1,num2){
return sum.apply(this,[num1,num2]);//傳入數(shù)組
}
alert(callSum1(10,10));//20
alert(callSum2(10,10));//20
真正的作用是擴(kuò)充作用域:一般是一個函數(shù)后面call一個作用域?qū)ο蟆?/p>
window.color = "red";
var o = {color:"blue"};
function sayColor(){
alert(this.color);
}
sayColor();//red
sayColor.call(this);//red
sayColor.call(window);//red
sayColor.call(o);//blue
按引用傳遞參數(shù),這里的引用指的是對象在內(nèi)存空間中地址的引用,有可能 2 個變量指向的是同一個內(nèi)存空間地址。如果將該引用傳遞到方法中,在方法中把這個引用中的數(shù)據(jù)改變了,那么指向這個引用的變量的值就都改變了。
基本包裝類型
為什么而存在?
為了操作基本類型的值,有3個特殊的引用類型:Boolean、Number、String。
通過包裝,具有引用類型的方法和屬性,同時也有基本類型的特殊行為。每次讀取一個基本類型的值,后臺就會創(chuàng)建一個對應(yīng)的基本包裝類型的對象,從而讓我們能調(diào)用方法來操作數(shù)據(jù)?;景b類型的實例調(diào)用typeof 返回“object”。轉(zhuǎn)為布爾值時都為true。Boolean(value)
var s1="some text";
var s2=s1.substring(2);
上面的代碼過程如下:
var s1 = new String("some text");//創(chuàng)建string類型的一個實例
var s2 = s1.substring(2);//在實例上調(diào)用指定的方法
s1 = null //銷毀這個實例
引用類型和基本包裝類型的區(qū)別
var s1 = "some text";
s1.color = "red";
alert(s1.color);//undefined
自動創(chuàng)建的基本包裝類型的對象,只存在于一行代碼的執(zhí)行瞬間,然后立即被銷毀。用 new 操作符創(chuàng)建的引用類型的實例,在執(zhí)行流離開當(dāng)前作用域之前一直都保存在內(nèi)存中。
把字符串傳給 object 構(gòu)造函數(shù),就會創(chuàng)建string實例;傳入數(shù)字,就會創(chuàng)建number實例;布爾值,則是布爾值實例。
var obj = new Object("some text");
alert(obj instanceof String);//true
但使用new調(diào)用基本包裝類型的構(gòu)造函數(shù),與直接調(diào)用同名轉(zhuǎn)型函數(shù)是不一樣的。
var value = "25";
var number =Number (value);//轉(zhuǎn)型函數(shù)
alert(typeof number);//"number"
var obj = new Number(value);//構(gòu)造函數(shù) 顯式調(diào)用
alert(typeof obj);//"object"
Boolean 類型
Boolean 類型是與布爾值對應(yīng)的引用類型。通過構(gòu)造函數(shù)創(chuàng)建一個 boolean 對象:
var booleanObject = new Boolean(true);Number類型
var numberObject = new Number(10);
Number類型還提供了一些用于數(shù)值格式化為字符串的方法。
var num = 10;
alert(num.toFixed(2));//"10:00"http://指定的小數(shù)位
3.String 類型
var stringObject = new String("Hello world");
- 字符方法——訪問特定位置的字符或字符編碼
var stringValue ="hello world";
alert(stringValue.charAt(1)); //"e"
alert(stringValue.charCodeAt(1)); //"101",表示e的字符編碼
- 字符串操作方法
concat()接受任意多個參數(shù),生成一個新的字符串副本,原來字符串不變。
3個基于字符串創(chuàng)建新字符串的方法:slice, substring, substr.都返回被操作字符串的一個子字符串,接受1-2個參數(shù),第一個參數(shù)指定子字符串的開始位置,第二個參數(shù)表示結(jié)束的位置。
var stringValue ="hello world";
alert(stringValue.slice(3));//"lo world"
alert(stringValue.substring(3));//"lo world"
alert(stringValue.substr(3));//"lo world"
alert(stringValue.slice(3,7));//"lo w",7表示子字符串最后一個字符后面的位置
alert(stringValue.substring(3,7));//"lo w",7表示子字符串最后一個字符后面的位置
alert(stringValue.substr(3,7));//"lo worl",7表示字符個數(shù)
- 字符串位置方法
indexOf()和lastIndexOf()可接受兩個參數(shù),第二個參數(shù)表示從哪個位置開始搜索
var stringValue = "Lorem ipsum dolor sit amet, consectetur elit";
var positions = new Array();
var pos = stringValue.indexOf("e");//在循環(huán)之外,首先找到"e"在字符串中的初始位置
while (pos>-1){//如果一個數(shù)組中沒有要找的字符,返回值為-1
positions.push(pos);//把e的初始位置push到數(shù)組中
pos = stringValue.indexOf("e",pos +1);//進(jìn)入循環(huán)后,每次都給indexOf()傳遞上一次位置加1,確保每次新搜索從上一次找到的子字符串后面開始
}
alert(positions); //"3,24,32,35,52"
- trim方法
創(chuàng)建一個副本,去掉前置和后綴所有空格