Prototype を使用したことがある人なら誰でも、Template というクラスがあることを知っています。使用例は次のとおりです。
var str = '#{what} はなくなったかもしれませんが、#{how} の時期があります';
var object = {
what : 'ツバメ'、
方法: 'return'
}
var template_1 = new Template(str);
var result = template_1.evaluate(object); 'result:',result );
//出力: 'ツバメは去ったかもしれませんが、戻る時期があります'
これは非常に便利なので、実装原理を簡単に分析してみましょう、これはソースコードでもあります 解釈上の注意。
まず、一般的な要件で使用されるいくつかの状況を見てみましょう。最初に、上記の例を使用してフォームを決定しましょう。置換部分は #{what} という形式のコンテンツです。オブジェクト オブジェクトへのキー。
ここで質問があります。オブジェクトがネストされたオブジェクトの場合、それをどのように置き換えるべきでしょうか?
つまり:
最初の #{what} は要件を満たせないため、ネストされたオブジェクトを置き換える場合は #{what.name} または #{what を記述することを厳密に規定しています。 [名前] }。
最初の例は次のように記述できます:
元の例ではテンプレートは str、パターンは一致ルール、オブジェクトは元の例のオブジェクトです。ここでは、評価メソッドの実装に焦点を当てます。
主に gsub メソッドを直接呼び出します。 gsub での置換メソッド。
考えられる状況
まず、オブジェクトが空のオブジェクトである場合、置換する必要がある部分を直接削除します
たとえば、
var str = '#{what} は次のようになります。消えましたが、#{how} の時間があります';
var object = {}
その後、単に return ' は消えたかもしれませんが、'
秒の時間があります、エスケープされた部分は直接保持されます
var str = '\# {何を} 行ってしまったかもしれないが、\#{どうやって} の時がある';
var object = {
何を : 'ツバメ',
どのように : '戻る'
}
その後、「\#{what} が起こった可能性がありますが、\#{how} の時間があります」を返します。
これらの状況は、コード、具体的には次のとおりです。
テンプレート.prototype.evaluate = function(object) {
//gsub(str,pattern, replace)
return gsub(this.template,this.pattern,function(match){
var before = match[ 1];//match here[ 1] は、Template.Pattern
var content = match[2];//match[1] の (^|.|r|n) の一致部分です (# {(.*? )})一致する部分
var expr = match[3];//ここでの match[1] は、Template.Pattern
の (.*?) の一致する部分です。//Example :
// s#{what} の場合、before='s'、content='#{what}'、expr='what'
// まず、object は空のオブジェクトです。直接削除します 置換部分
if(object == null){
return (match[1] '')
}
//2 番目に、エスケープ部分は直接保持されます
if (before == '\'){
return content;
}
//上記の 2 つの状況に加えて、次のような通常の置換プロセスがあります。
var ctx = object;
//前に述べたように、次の通常のルールは、ネストされたオブジェクトを照合するためのものです。最後の (.|[|$) を見て、ネストされたサブオブジェクトの一致があるかどうかを判断します。
//'.' in #{what.name}
//または '[' in #{what[name]}
//つまり、次の一致[3]
var pattern = /^([^.[] |[((?:.*?[^\])?)])(.|[|$)/
match = pattern.exec( expr );
while (match != null) {
if(/^[/.test(match[1])){
var comp = match[2].replace(/ \ \]/g, ']');
}else{
var comp = match[1];
ctx = ctx[comp];//ctx[comp] が A の場合string の場合は、ctx[comp] がまだオブジェクトである場合は、次のステップを実行できます。申し訳ありませんが、残業を続けてください。
if (null == ctx || '' == match[3]){//置換する必要があるのはオブジェクトのネストされたサブオブジェクトではない場合、ループを直接中断します。交換は成功しました。仕事は休みです。
break;
}
//以下はキーワードを削除するだけであり、他の操作はループ内で使用され、繰り返されます。
if('[' == match[3]){
expr = expr.substring(match[1].length)
}else{
expr = expr.substring(match[0 ].length)
}
match = pattern.exec(expr)
ctx の前に戻る
}); >
もちろん、ソースコードはそれほど単純ではありません。str の不正な文字を置き換えたり、置き換えを文字列として処理したりするなど、書き込みの検出と判断も含まれます。詳細についてはソースコードを確認できます。
少し複雑になるかもしれないのは、置換が文字列である場合の処理です。gsub と Template の間にネストされた呼び出しがありますが、最終的には関数をスローバックするだけです。