欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Prototype源碼淺析 String部分(二)

 更新時(shí)間:2012年01月16日 00:15:28   作者:  
本文接著上面的String部分,繼續(xù)下面表格的部分
格式 camelize | capitalize |  underscore |  dasherize  | inspect          
變形 toArray |  succ  | times
這里面一個(gè)有用的方法是inspect,按照參考手冊(cè)的說明,他的作用是“返回該字符串針對(duì)調(diào)試的字符串表現(xiàn)形式(即用單引號(hào)或雙引號(hào)包括起來,并使用 '\' 對(duì)特殊字符進(jìn)行轉(zhuǎn)義)”,在Object的toJSON里面也涉及到這個(gè)方法。

  既然涉及到需要轉(zhuǎn)義的字符,我們自然要一份轉(zhuǎn)義字符信息,下面直接給出:
復(fù)制代碼 代碼如下:

String.specialChar = {
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'\\': '\\\\'
}

【在JSON.js里面,多了一個(gè)'"',因?yàn)镴SON里面string里面是不能出現(xiàn)"的,所以需要轉(zhuǎn)義】

  第一步,當(dāng)然是要替換特殊的轉(zhuǎn)義字符,初始版本:
復(fù)制代碼 代碼如下:

function inspect() {
return this.replace(/[\b\t\n\f\r\\]/,function(a){
return String.specialChar[a];
});
}

  對(duì)于JSON形式來說,雙引號(hào)是必須的,因此,我們應(yīng)該可以選擇自己的返回形式,所以,給inspect一個(gè)參數(shù)useDoubleQuotes,默認(rèn)是用單引號(hào)返回字符串的。
復(fù)制代碼 代碼如下:

function inspect(useDoubleQuotes) {
var escapedString = this.replace(/[\b\t\n\f\r\\]/,function(a){
return String.specialChar[a];
});
if (useDoubleQuotes){
return '"' + escapedString.replace(/"/g, '\\"') + '"';
}
return "'" + escapedString.replace(/'/g, '\\\'') + "'";
}

  現(xiàn)在這跟源碼中的功能差不多,不過Prototype源碼中的實(shí)現(xiàn)方式并不是這樣的,主要區(qū)別在于escapedString這一段。源碼中直接列出來所有的控制字符,表示為[\x00-\x1f],外加'\'就是[\x00-\x1f\\],因此改造上面的初始版本就是:
復(fù)制代碼 代碼如下:

function inspect(useDoubleQuotes) {
var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) {
if (character in String.specialChar) {
return String.specialChar[character];
}
return character ;
});
if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
return "'" + escapedString.replace(/'/g, '\\\'') + "'";
}
[html]
附,ASCII控制字符編碼表,對(duì)應(yīng)\x00-\x1f:


如果發(fā)現(xiàn)除了String.specialChar中的字符,還有其他的控制字符,源碼中也有一步處理,就是將控制字符轉(zhuǎn)變?yōu)閡nicode的表示形式,因?yàn)檫@個(gè)方法本身就是要獲得字符串的形式。
比如垂直制表符'\v'。'\v'.inspect() -->'\u000b'
完整版本:
[code]
function inspect(useDoubleQuotes) {
var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) {
if (character in String.specialChar) {
return String.specialChar[character];
}
return '\\u00' + character.charCodeAt().toPaddedString(2, 16);
});
if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
return "'" + escapedString.replace(/'/g, '\\\'') + "'";
}

  其中toPaddedString(length[, radix])將當(dāng)前 Number 對(duì)象轉(zhuǎn)換為字符串,如果轉(zhuǎn)換后的字符串長度小于 length 指定的值,則用 0 在左邊補(bǔ)足其余的位數(shù)??蛇x的參數(shù) radix 用于指定轉(zhuǎn)換時(shí)所使用的進(jìn)制。這是Prototype中Number的一個(gè)擴(kuò)展,暫時(shí)知道即可。
  因此'\v'.charCodeAt().toPaddedString(2, 16)就是將'\v'的字符編碼轉(zhuǎn)換成16進(jìn)制的兩位編碼符[操作字符不會(huì)范圍有限制,因此不會(huì)超出],最后冠以'\u00'開頭即可。

方法說明:
toArray:將字符串拆分為字符數(shù)組。
succ:根據(jù) Unicode 字母表轉(zhuǎn)換字符串最后的字符為后續(xù)的字符
times:將字符串重復(fù)。
  對(duì)應(yīng)具體的實(shí)現(xiàn)也很簡(jiǎn)單,String部分的重要之處在于后面的腳本,JSON和替換處理,其他都是增強(qiáng)性質(zhì)的。
復(fù)制代碼 代碼如下:

function toArray() {
return this.split('');
}

  其中split('')就將字符串打撒為單個(gè)字符,并以數(shù)組形式返回,如果還要再增強(qiáng),可以給一個(gè)參數(shù)給toArray來指定分隔符。
復(fù)制代碼 代碼如下:

function toArray(pattern) {
return this.split(pattern);
}
console.log(toArray.call('my name is xesam',' '));//["my", "name", "is", "xesam"]

就是對(duì)split的使用而已,不過源碼中并沒有這么做,因?yàn)椴]有這個(gè)必要。

復(fù)制代碼 代碼如下:

function succ() {
return this.slice(0, this.length - 1) + String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
}

  這里主要的就是fromCharCode和charCodeAt方法的使用。從代碼中也可以看出,兩者的明顯區(qū)別是fromCharCode是String的靜態(tài)方法,而charCodeAt是字符串的方法(掛在String.prototype上面)。然后兩者的作用正好相反,下面是http://www.w3school.com.cn給出的解釋:
  fromCharCode() 可接受一個(gè)指定的 Unicode 值,然后返回一個(gè)字符串。
  charCodeAt() 方法可返回指定位置的字符的 Unicode 編碼。這個(gè)返回值是 0 - 65535 之間的整數(shù)。
  具體到succ,以字符串‘hello xesam'為例,先獲取除結(jié)尾字符外的所有字符‘hello xesa',然后加上Unicode表中‘m'后面的一個(gè)字符‘n',因此結(jié)果就是‘hello xesan'
以此為基礎(chǔ),我們要打印從‘a(chǎn)'到‘z'的所有字母,可以用以下的函數(shù):
復(fù)制代碼 代碼如下:

function printChar(start,end){
var s = (start + '').charCodeAt()
var e = (end + '').charCodeAt();
if(s > e){
s = [e,e=s][0];
}
for(var i = s ;i <= e; i++){
console.log(String.fromCharCode(i));
}
}
printChar('a','z');

復(fù)制代碼 代碼如下:

function times(count) {
return count < 1 ? '' : new Array(count + 1).join(this);
}

  times作用是重復(fù)整個(gè)字符串,其主要思想就是將當(dāng)前字符作為數(shù)組的連接符調(diào)用join來獲得預(yù)期結(jié)果。當(dāng)然用循環(huán)添加也可以,不過沒這么簡(jiǎn)潔。
如果要重復(fù)字符串里面的每個(gè)字符,可以用相同的思想:
復(fù)制代碼 代碼如下:

String.prototype.letterTimes = function(count){
var arr = [];
arr.length = count + 1;
return this.replace(/\w/g,function(a){
return arr.join(a);
})
}
console.log('xesam'.letterTimes(3));//xxxeeesssaaammm


camelize | capitalize | underscore | dasherize這四個(gè)主要是關(guān)于變量名轉(zhuǎn)換的。
camelize : 將一個(gè)用橫線分隔的字符串轉(zhuǎn)換為 Camel 形式
capitalize :將一個(gè)字符串的首字母轉(zhuǎn)換為大寫,其它的字母全部轉(zhuǎn)為小寫。
underscore :將一個(gè) Camel 形式的字符串轉(zhuǎn)換為以下劃線("_")分隔的一系列單詞。
dasherize :將字符串中的下劃線全部替換為橫線("_" 替換為 "-")。
  最明顯的,可以用在CSS屬性與DOM的style屬性的相互轉(zhuǎn)換中【class與float不屬于此范疇】。對(duì)應(yīng)到上面的方法中,將CSS屬性轉(zhuǎn)換為對(duì)應(yīng)的DOM的style屬性可以使用camelize 方法,但是反過來卻沒有這個(gè)方法,因此必須連續(xù)調(diào)用underscore -> dasherize 方法才行。
復(fù)制代碼 代碼如下:

function camelize() {
return this.replace(/-+(.)?/g, function(match, chr) {
return chr ? chr.toUpperCase() : '';
});
}

  核心是replace方法的使用,其他挺簡(jiǎn)單,參見《淺析字符串的replace方法應(yīng)用》

復(fù)制代碼 代碼如下:

function capitalize() {
return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
}

  這里注意charAt(charAt() 方法可返回指定位置的字符。)與charCodeAt的區(qū)別就可以了。

復(fù)制代碼 代碼如下:

function underscore() {
return this.replace(/::/g, '/')
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
.replace(/([a-z\d])([A-Z])/g, '$1_$2')
.replace(/-/g, '_')
.toLowerCase();
}

實(shí)例來說明步驟:
復(fù)制代碼 代碼如下:

'helloWorld::ABCDefg'.underscore()
//'helloWorld::ABCDefg'
.replace(/::/g, '/') //'helloWorld/ABCDefg'
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')//helloWorld/ABC_Defg
.replace(/([a-z\d])([A-Z])/g, '$1_$2') //hello_World/ABC_Defg
.replace(/-/g, '_') //hello_World/ABC_Defg
.toLowerCase(); //hello_world/abc_defg

這個(gè)方法只適合Camel 形式的,就是得有‘峰'。
復(fù)制代碼 代碼如下:

function dasherize() {
return this.replace(/_/g, '-');
}

這個(gè)就是單純的字符替換而已。
來自小西山子

相關(guān)文章

最新評(píng)論