添加到String.prototype中的方法比较多,不过归结起来,大致分为下面几类:
分类 |
方法名 |
原始能力增强 |
strip | include | startsWith | endsWith | empty | blank |
格式 |
camelize | capitalize | underscore | dasherize | inspect |
变形 |
toArray | succ | times |
替换 |
interpolate | sub | scan | truncate | gsub |
HTML处理 |
stripTags | escapeHTML | unescapeHTML |
参数序列化 |
toQueryParams |
JSON处理 |
unfilterJSON | isJSON | evalJSON | parseJSON |
脚本处理 |
stripScripts | extractScripts | evalScripts |
Starting from the basic original ability enhancement, the following is the specific implementation, which is easy to understand:
(function(s){
function strip(){
return this.replace(/^s /,'').replace(/s $/, '');
}
function include(pattern){
return this.indexOf(pattern) > -1;//split
}
function startsWith(pattern) {
return this.lastIndexOf(pattern, 0) === 0;
}
function endsWith(pattern) {
var d = this.length - pattern.length;
return d >= 0 && this.indexOf(pattern, d) === d;
}
function empty() {
return this == '';
}
function blank() {
return /^s*$/.test(this);
}
s.strip = String.prototype.trim || strip;
s.include = include;
s.startsWith = startsWith;
s.endsWith = endsWith;
s.empty = empty;
s.blank = blank;
})(String.prototype);
The strip above is $.trim in jquery, and most of them seem to be trim. The tragedy of directly extending the native prototype is revealed here, because the trim method is implemented in subsequent JS implementations (such as chrome), which is self-defeating.
function strip(){
return this.replace (/^s /,'').replace(/s $/,'');
}
The replace(/^s /,'') here is trimLeft, replace(/s $/,'') is trimRight, but these two methods are not available in Prototype.String.
The following is the more interesting part of this part:
When I was watching this paragraph, I was very confused about startsWith and endsWith. Logically speaking, indexOf can be used for startsWith. Here lastIndexOf is used. Later, I checked the implementation of Prototype1.6 version:
function startsWith(pattern) {
return this.indexOf(pattern) === 0;
}
function endsWith(pattern) {
var d = this.length - pattern.length ;
return d >= 0 && this.lastIndexOf(pattern) === d;
}
It can be seen that startsWith used indexOf in the previous version, but it was modified in version 1.7 The implementation of startsWith. In version 1.7:
In the implementation of startsWith, lastIndexOf searches from back to front, but the starting point (fromindex) is set to 0, so you only need to detect the beginning once.
In the endsWith implementation, indexOf searches from front to back. Since the length of the string is variable, the length is calculated here, and then the starting point (fromindex) is determined, so the end only needs to be detected once.
The performance optimization here is that in the 1.6 implementation, if there is no match at the beginning (that is, startsWith is not established), indexOf will still search backward until it finds a match or the end of the string, which is a waste . For example, for the following operation:
'abcdefgabcdefg'.startsWith('abc')
In the implementation of version 1.6 and version 1.7, there is no difference, but let's convert it:
'abcdefgabcdefg'.startsWith('xesam')
In the 1.6 implementation, the indexOf operation inside startsWith will continue after the a at the beginning does not match x. Although there is no need to continue, the indexOf will still continue. Search backward until a matching 'xesam' is found or until the end of the string.
In the 1.7 implementation, lastIndexOf inside startsWith is searched in reverse (fromIndex=0), so after the beginning a does not match x, the operation stops because lastIndexOf has reached the end.
In this comparison, if the string to be detected is very long, there will be a significant difference in the efficiency of the two implementation methods.
The principle of endsWith is the same.