【JS學(xué)習(xí)筆記】第5章


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)

IMG_8127.JPG

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"
  1. Boolean 類型
    Boolean 類型是與布爾值對應(yīng)的引用類型。通過構(gòu)造函數(shù)創(chuàng)建一個 boolean 對象:
    var booleanObject = new Boolean(true);

  2. 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)建一個副本,去掉前置和后綴所有空格
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容