SoFunction
Updated on 2025-04-13

Prototype String Object Learning


// Static method of String object
(String, {
interpret: function(value) {
return value == null ? '' : String(value);
},
specialChar: {
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'\\': '\\\\'
}
});

(, (function() {

//Internal method, initialize replacement parameters for gsub and sub functions
function prepareReplacement(replacement) {
if ((replacement)) return replacement;
var template = new Template(replacement);
return function(match) { return (match) };
}

//Replace all pattern-compliant strings with replacement
//Note that when replacement is not a function, there will be a recursive call here, where the parameter pattern will become
//You can refer to the Template's evaluation method. The construction here is very clever. The else part in the while loop will handle the result of this recursive call
function gsub(pattern, replacement) {
var result = '', source = this, match;
replacement = prepareReplacement(replacement);

if ((pattern))
pattern = (pattern);

//If the pattern parameter is null or '', split the entire string by a single character, and add replacement before and after each character
if (!( || )) {
replacement = replacement('');
return replacement + ('').join(replacement) + replacement;
}

while ( > 0) {
//If source matches pattern
if (match = (pattern)) {
//Fetch out the string before matching
result += (0, );
//Match replacement
result += (replacement(match));
// Assign the part after the matching character to source for the next match
source = ( + match[0].length);
} else { //If the source does not match the pattern, add the source directly to the result, empty the source, end the loop
result += source, source = '';
}

}
return result;
}

//The basic meaning is the same as gsub, except that there is an extra count parameter, indicating how many times it needs to be replaced
function sub(pattern, replacement, count) {
replacement = prepareReplacement(replacement);
count = (count) ? 1 : count;

return (pattern, function(match) {
if (--count < 0) return match[0];
return replacement(match);
});
}

//Make an iterator call to a pattern-compliant string
function scan(pattern, iterator) {
(pattern, iterator);
return String(this);
}

//Truncate the string according to the given length
function truncate(length, truncation) {
length = length || 30;
truncation = (truncation) ? '...' : truncation;
return > length ?
(0, length - ) + truncation : String(this);
}

//Remove the spaces before and after the string
function strip() {
return (/^\s+/, '').replace(/\s+$/, '');
}

//Exclude the html tag of the string
function stripTags() {
return (/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '');
}

//Exclude script tags in string
function stripScripts() {
return (new RegExp(, 'img'), '');
}

//Get script content in string
function extractScripts() {
var matchAll = new RegExp(, 'img');
var matchOne = new RegExp(, 'im');
return ((matchAll) || []).map(function(scriptTag) {
return ((matchOne) || ['', ''])[1];
});
}

//Execute script content in string
function evalScripts() {
return ().map(function(script) { return eval(script) });
}

//Escape HTML content, such as replacing special characters such as '<>&' with standard HTML expressions
function escapeHTML() {
= this;
return ;
}

function unescapeHTML() {
var div = ('div');
= ();
return [0] ? ( > 1 ?
$A().inject('', function(memo, node) { return memo+ }) :
[0].nodeValue) : '';
}

//Segment the string into query parameter form according to the separator parameter
function toQueryParams(separator) {
var match = ().match(/([^?#]*)(#.*)?$/);
if (!match) return { };

return match[1].split(separator || '&').inject({ }, function(hash, pair) {
if ((pair = ('='))[0]) {
var key = decodeURIComponent(());
var value = > 1 ? ('=') : pair[0];
if (value != undefined) value = decodeURIComponent(value);

if (key in hash) {
if (!(hash[key])) hash[key] = [hash[key]];
hash[key].push(value);
}
else hash[key] = value;
}
return hash;
});
}

function toArray() {
return ('');
}

//Return the character of the string
function succ() {
return (0, - 1) +
(( - 1) + 1);
}

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

//Convert css style strings into script form
function camelize() {
var parts = ('-'), len = ;
if (len == 1) return parts[0];

var camelized = (0) == '-'
? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
: parts[0];

for (var i = 1; i < len; i++)
camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);

return camelized;
}

//Capital letter
function capitalize() {
return (0).toUpperCase() + (1).toLowerCase();
}

//'borderBottomWidth'.underscore();
// -> 'border_bottom_width'
function underscore() {
return (/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
}

//'border_bottom_width'.dasherize();
// -> 'border-bottom-width'
function dasherize() {
return (/_/,'-');
}

//Returns a debug-oriented version of the string (returns a string used to adjust)
function inspect(useDoubleQuotes) {
var escapedString = (/[\x00-\x1f\\]/, function(match) {
var character = [match[0]];
return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
});
if (useDoubleQuotes) return '"' + (/"/g, '\\"') + '"';
return "'" + (/'/g, '\\\'') + "'";
}

function toJSON() {
return (true);
}

function unfilterJSON(filter) {
return (filter || , '#{1}');
}

function isJSON() {
var str = this;
if (()) return false;
str = (/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
}

//Strips comment delimiters around Ajax JSON or JavaScript responses. This security method is called internally.
function evalJSON(sanitize) {
var json = ();
try {
if (!sanitize || ()) return eval('(' + json + ')');
} catch (e) { }
throw new SyntaxError('Badly formed JSON string: ' + ());
}

function include(pattern) {
return (pattern) > -1;
}

function startsWith(pattern) {
return (pattern) === 0;
}

function endsWith(pattern) {
var d = - ;
return d >= 0 && (pattern) === d;
}

function empty() {
return this == '';
}

function blank() {
return /^\s*$/.test(this);
}

//Same as Template's evaluate method
function interpolate(object, pattern) {
return new Template(this, pattern).evaluate(object);
}

return {
gsub: gsub,
sub: sub,
scan: scan,
truncate: truncate,
strip: ? : strip,
stripTags: stripTags,
stripScripts: stripScripts,
extractScripts: extractScripts,
evalScripts: evalScripts,
escapeHTML: escapeHTML,
unescapeHTML: unescapeHTML,
toQueryParams: toQueryParams,
parseQuery: toQueryParams,
toArray: toArray,
succ: succ,
times: times,
camelize: camelize,
capitalize: capitalize,
underscore: underscore,
dasherize: dasherize,
inspect: inspect,
toJSON: toJSON,
unfilterJSON: unfilterJSON,
isJSON: isJSON,
evalJSON: evalJSON,
include: include,
startsWith: startsWith,
endsWith: endsWith,
empty: empty,
blank: blank,
interpolate: interpolate
};
})());

(, {
div: ('div'),
text: ('')
});

();
//The following estimate is to solve the browser compatibility problem
if ('<\n>'.escapeHTML() !== '<\n>') {
= function() {
return (/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
};
}

if ('<\n>'.unescapeHTML() !== '<\n>') {
= function() {
return ().replace(/</g,'<').replace(/>/g,'>').replace(/&/g,'&');
};
}