JS拾荒の字串

Cris_冷崢子發表於2018-03-10
  • 普通字串拼接的問題
  • 模板字串的簡單實現
  • 字串模板中的標籤函式
  • ejs模板引擎核心原理
    • 什麼是模板引擎
    • 設計思路
    • 實現
  • 字串常用方法
    • startsWith
    • endsWith
    • includes
    • padStart

js字串小記,相關備忘,保持更新中...

普通字串拼接的問題

  1. 普通字串拼接時候一串字元裡不能換行(對應的模板字串中是能的)
let str = '我是一串

普通的字串';  //此處進行了換行,會報錯

console.log(str);
複製程式碼

解決方案:在準備換行之前使用\轉義

let str = '我是一串\
\
普通的字串';  //此處進行了換行,會報錯

console.log(str);
複製程式碼
  1. '""需要手動轉義 模板字串中若要輸出單雙引號不再需要加上\
let str = `'單引號"雙引號`;
console.log(str);
複製程式碼

但模板字串的 ` 還是需要轉義的哦!

模板字串的簡單實現

let name = 'ahhh';
let str = '你好,${name}';
function tmpstr(str){
    str.replace(/\$\{(.*?)\}/,function(){
        return eval(arguments[1]);
    })
}

<<< 輸出
你好,ahhh
複製程式碼

字串模板中的標籤函式

let name = 'ahhh';
let where = '艾澤拉斯';

let str = tag`${name}你要去${where}買菜嗎?`
function tag(strings,...tags){
    console.log(arguments);
    console.log(strings);
    console.log(tags);
}
console.log(str); 
//直接輸出str 其實就是呼叫tag函式 `xx`部分就相當於函式傳參

<<< 輸出
{
    ‘0’:['','你要去','買菜嗎'] //注意這裡這個陣列是以${}為分隔符的
    ,‘1’:‘ahhh’
    ,‘2’:‘艾澤拉斯’
}

[ '', '你要去', '買菜嗎?' ]

[ 'ahhh', '艾澤拉斯' ]
複製程式碼

字串模板中的每一對${}稱之為一對標籤。除卻標籤的部分即為普通字串。

tag函式的arguments引數中的第一個引數是字串模板中的所有普通字元,但需要注意的一點是${}處於整個模板字串開頭或結尾時會在第一個引數的陣列的開頭或結尾多一個''字串,

另外若兩隊標籤緊靠在一起,像這樣${a}${b},那標籤a和標籤b之間也會多一個''

總之,有x${}就會在整個字串中切2x刀,分成2x+1份(strings+tags)。

推薦閱讀 ES6 標籤模板

ejs模板引擎核心原理

什麼是模板引擎

模板引擎就是把資料物件渲染到指定模板指定位置上。每種模板引擎都有自己專門標記指定位置的符號,像ejs,就是以<%...%><%=...%>來作為識別符號號的。

設計思路

關鍵詞:withFunction字串拼接

先說with,with是一種作用域,它的作用域範圍是它所接受的物件

在一個with作用域裡,我們能直接拿到它所接受物件的屬性(你可以理解成with把這個物件解構了)

let obj = {
    name:'ahhh'
    ,age:'111'
    ,hobby:'sleep'
}
with(obj){
    console.log(`${name}今年${age}歲,TA唯一的興趣就是${hobby}`)
}

<<<
ahhh今年111歲,TA唯一的興趣就是sleep
複製程式碼

想想我們平時是怎麼使用模板引擎的?是不是經常for data.lengthif(data.xx===)if(!data.xx)這樣的。

這裡的data就像我們上面栗子中的obj

let data = {
    user:{name:ahhh}
}

(function(){
    let tpl = '';
    with(data){
        if(user){
            tpl += `hi~${user.name}`;
        }else{
            tpl += `to login~`;
        }
    }
    retrun tpl;
})...
複製程式碼

和我們使用ejs時的樣子進行對比

<%if(user){%>
    hi~<%=user.name%>;
<%}else{%>
   to login~
<%}%>
複製程式碼

實現

  1. 把ejs的這種形式轉換成with與字串拼接的形式
function render(filepath,data,callbcak){
	fs.readFile(filepath,'uf8',function(err,str){
    	if(err)return callbcak(err,null);
        let head = "let tpl =``;\r\nwith(data){\r\ntpl=`";
        str = str.replace(/<%=[\w\W]+?%>/g,function(){
    	    return '${'+arguments[1]+'}';
        });
        str = str.replace(/<%[\w\W]+?%>/g,function(){
    	    return "`;\r\n"+arguments[1]+"\r\ntpl +=`";
        });
        let tail = "`}\r\nreturn tpl;";
        let html = head+str+tail;
       ...
    });
}
複製程式碼

注意為了讓tpl形成閉合,我們在head部分的末尾追加了一個 tpl=`,在tail開頭時也追加了一個 `

  1. 將拼接後的字串傳遞給Function生成一個真正函式
...
let fn = Function('data',html);
let ret = fn(data);
callbcak(null,ret);
...
複製程式碼

上面的整個實現是相容express模板引擎規範的

這個render函式的第三個引數callbcak是express中res.render所傳遞進render中的done回撥(如果編譯成功就將編譯成功後的html作為響應返回,如果失敗則返回錯誤資訊)

字串常用方法

startsWith

let url = 'https://www.baidu.com';
let boolean = url.startsWith('https');
console.log(boolean);

<<<
true
複製程式碼

[danger] 注意: 這個方法名必須要吐槽一下加深一下印象?md?帶個s??看見沒有,它居然帶s!!臥槽,你說你憑啥要帶個s???,還有下面的endsWith,臥槽,你說你帶s就算了,你能不統一下,你padStart又不帶s了???

endsWith

let ext = '123.jpg';
let boolean = ext.endsWith('.jpg');
console.log(boolean);

<<<
true
複製程式碼

includes

let str = 'hello,world!';
let boolean = str.includes('world');
console.log(boolean);

<<<
true
複製程式碼

padStart

.padStart(minlength,fill)

第一個引數為字串最小長度,第二個引數為填充字元,若字串小於最小長度會用填充字元在開頭出開始填充(padEnd這是在結尾處開始填充)。

let d = new Date();
let h = d.getHours().toString();
let m = d.getMinus().toString();
let s = d.getSeconds().toString();
let t = `${h.padStart(2,0)}:${m.padStart(2,0)}:${s.padStart(2,0)}`;
setInterval(function(){
    console.log(t);
},1000)
複製程式碼

相關文章