JavaScript機能を拡張する正しい方法(翻訳文)

6135 ワード

朝は「JavaScript毎週導読」「第三期」という文章を見ましたが、中から一つの文章(Extending JavaScript、C The Right Way)が発見されました.いいと思います.翻訳して皆さんと共有します.本文は一字一句を翻訳するのではなく、できるだけ分かりやすく説明します.
Extensding JavaScript、C The Right Way以下は翻訳文JavaScriptに多くの強力な方法が内蔵されていますが、時々必要な機能が内蔵されていない場合があります.JavaScript機能を優雅に拡張するにはどうすればいいですか?例えば、capitalize()方法を追加して、頭文字の大文字を実現したいです.普通はこう書きます.
 
  
if(!String.prototype.capitalize)
{
String.prototype.capitalize = function()
{
return this.slice(0,1).toUpperCase() + this.slice(1).toLowerCase();
}
}
上のコードは正常に使えますが、どこかに下記のコードがあります.
 
  
var strings = "yay";
for(i in strings) console.log(i + ":" + strings[i]);
私たちが得た結果はこうです.
0:y
1:a
2:y
capitalize:function(){return this.slice(0,1).toUpperCase()+this.slice(1).toLowerCase();
これは明らかに私たちが欲しい結果ではないです.私たちが追加した方法を出力した理由は、enumerable属性がデフォルトでtrueです.
この問題を回避するために簡単にエニュメレーション属性をfalseに設定することで、defineProperty方法を使用して機能の拡張を行うことができます.
 
  
if(!String.prototype.capitalize)
{
Object.defineProperty(String.prototype, 'capitalize',
{
value: function()
{
return this.slice(0,1).toUpperCase() + this.slice(1).toLowerCase();
},
enumerable: false
});
}
このコードを再実行します.
 
  
var strings = "yay";
for(i in strings) console.log(i + ":" + strings[i]);
私たちが得た結果は:
0:y
1:a
2:y
循環で出力されていないものは存在しないという意味ではないので、下記のコードで定義を確認できます.
 
  
var strings = "yay";
console.log(strings.capitalize)
出力:
 
  
function () { return this.slice(0, 1).toUpperCase() + this.slice(1).toLowerCase(); }
このようにJavaScript機能を拡張するのは比較的に柔軟です.私たちはこのような方法で自分たちのオブジェクトを定義し、いくつかのデフォルト値を設定することができます.
以下は他の拡張方法です.自分のプロジェクトで使用できます.
String.pxToInt()
「200 px」という文字列を数字200に変換します.
 
  
if(!String.prototype.pxToInt)
{
Object.defineProperty(String.prototype, 'pxToInt',
{
value: function()
{
return parseInt(this.split('px')[0]);
},
enumerable: false
});
}
String.isHex()
文字列が16進数で表されているかどうかを判断します.例えば、「〓CCC」や「〓CACA」などです.
 
  
if(!String.prototype.isHex)
{
Object.defineProperty(String.prototype, 'isHex',
{
value: function()
{
return this.substring(0,1) == '#' &&
(this.length == 4 || this.length == 7) &&
/^[0-9a-fA-F]+$/.test(this.slice(1));
},
enumerable: false
});
}
Stering.reverse()
文字列の反転:
 
  
if(!String.prototype.reverse)
{
Object.defineProperty(String.prototype, 'reverse',
{
value: function()
{
return this.split( '' ).reverse().join( '' );
},
enumerable: false
});
}
String.word Count()
単語の数を統計して、スペースで分けます.
 
  
if(!String.prototype.wordCount)
{
Object.defineProperty(String.prototype, 'wordCount',
{
value: function()
{
return this.split(' ').length;
},
enumerable: false
});
}
Stering.httml Entties()
これは特殊文字としてエンコードされています.
 
  
if(!String.prototype.htmlEntities)
{
Object.defineProperty(String.prototype, 'htmlEntities',
{
value: function()
{
return String(this).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"');
},
enumerable: false
});
}
String.strippTags()
HTMLタグを削除:
 
  
if(!String.prototype.stripTags)
{
Object.defineProperty(String.prototype, 'stripTags',
{
value: function()
{
return this.replace(/]+>/gi, '');
},
enumerable: false
});
}
String.trim()
先頭のスペースを削除:
 
  
if(!String.prototype.trim)
{
Object.defineProperty(String.prototype, 'trim',
{
value: function()
{
return this.replace(/^\s*/, "").replace(/\s*$/, "");
},
enumerable: false
});
}
String.strip NonAlpha()
非文字を削除:
 
  
if(!String.prototype.stripNonAlpha)
{
Object.defineProperty(String.prototype, 'stripNonAlpha',
{
value: function()
{
return this.replace(/[^A-Za-z ]+/g, "");
},
enumerable: false
});
}
Object.sizof()
統計対象の大きさは、{one:「and」などで、two:「and」は2である.
 
  
if(!Object.prototype.sizeof)
{
Object.defineProperty(Object.prototype, 'sizeof',
{
value: function()
{
var counter = 0;
for(index in this) counter++;
return counter;
},
enumerable: false
});
}
このようにJS元のオブジェクトの機能を拡張するのはいいですが、必要でない限り(多くのプロジェクトで使用されています)、直接元のオブジェクトに機能を拡張することは推奨されません.
また、文章中のpxToInt()方法は必要なく、JS中のパーrseInt()は直接にこのような機能を完成することができます.パーrsetInt(「200 px」)==200
httml Enttiesの方法に問題があるようです.次のもう一つを提供します.
 
  
if(!String.prototype.htmlEntities)
{
Object.defineProperty(String.prototype, 'htmlEntities',
{
value: function()
{
var div = document.createElement("div");
if(div.textContent){
div.textContent=this;
}
else{
div.innerText=this;
}
return div.innerHTML;
},
enumerable: false
});
}