自定义实现JavaScript的String方法
length方法
function String(str) {
this.str = str;
this.length = 0;
var i=0;
while(str[i]) {
i++;
}
this.length = i;
}
var str = new String('abc');
console.log(str);
charAt
String.prototype.charAt = function(index) {
return this.length <=index? "": this.str[index];
}
concat
- 方法用于连接两个字符串,返回一个新字符串,不改变原字符串。
String.prototype.concat = function() {
let st =Object.keys(this).filter(index => index != 'length').reduce((total, index)=>{
return total += this[index];
}, "")
for(let i=0; i<arguments.length; i++) {
st += arguments[i];
}
return st;
}
自定义方法
String.prototype.return_all = function() {
let st = "";
Object.keys(this).forEach((item, index)=> {
if(index !== this.length) {
st += this[index];
}
})
return st;
}
String.prototype.return_sub = function(start, end) {
let st = "";
Object.keys(this).forEach((item, index)=> {
if(index !== this.length && index >=start && index < end) {
st += this[index];
}
})
return st;
}
slice
- 用于从原字符串取出子字符串并返回,不改变原字符串。
- 它的第一个参数是子字符串的开始位置,第二个参数是子字符串的结束位置(不含该位置)。
String.prototype.slice = function() {
let start = 0;
let end = 0;
if(arguments.length ===1 && arguments[0] === 0 || (arguments.length === 0)) {
let st = "";
Object.keys(this).forEach((item, index)=> {
if(index !== this.length) {
st += this[index];
}
})
return st;
}
if(arguments.length === 1) {
if(arguments[0] > 0){
start = arguments[0];
end = this.length;
}else {
start = arguments[0] + this.length;
end = this.length;
}
}else if(arguments.length === 2) {
start = arguments[0]>=0 ? arguments[0] : arguments[0] + this.length;
end = arguments[1]>=0 ? arguments[1] : arguments[1] + this.length;
}
if(start > end) {
return "";
}
return this.return_sub(start, end);
}
console.log( str.slice(0, 4) );
console.log(str.slice(4));
console.log(str.slice(-6));
console.log(str.slice(0, -6));
console.log(str.slice(-2, -1));
console.log(str.slice(2, 1));
substring
- substring方法用于从原字符串取出子字符串并返回,不改变原字符串,跟slice方法很相像。
- 它的第一个参数表示子字符串的开始位置,第二个位置表示结束位置(返回结果不含该位置)。
String.prototype.substring = function() {
let start = 0;
let end = 0;
if(arguments.length === 0) {
end = this.length;
}else if(arguments.length === 1) {
if(arguments[0]>0) {
start = arguments[0];
end = this.length;
}else {
start = 0;
end = this.length;
}
}else if(arguments.length === 2){
start = arguments[0]>=0? arguments[0]: 0;
end = arguments[1]>=0? arguments[1]: 0;
if(start > end) {
let t ;
t = start;
start = end;
end = t;
}
}
return this.slice(start, end);
}
console.log( str.substring(0, 4) );
console.log( str.substring(4) );
console.log( str.substring(10, 4) );
console.log( str.substring(4, 10) );
console.log( str.substring(-3) );
console.log( str.substring(4, -3) );
substr
- substr方法用于从原字符串取出子字符串并返回,不改变原字符串,跟slice和substring方法的作用相同。
- substr方法的第一个参数是子字符串的开始位置(从0开始计算),第二个参数是子字符串的长度。
- 如果第一个参数是负数,表示倒数计算的字符位置。如果第二个参数是负数,将被自动转为0
String.prototype.substr = function() {
let start = 0;
let end = 0;
if(arguments.length === 0) {
return this.return_all();
}else if(arguments.length === 1) {
if(arguments[0]>0) {
start = arguments[0];
end = this.length;
}else {
start = arguments[0] + this.length;
end = this.length;
}
}else if(arguments.length === 2) {
start = arguments[0]>0?arguments[0]: arguments[0] + this.length;
end = arguments[1]>0? start + arguments[1] : 0;
}
return this.slice(start, end);
}
console.log(str.substr(4, 6));
console.log(str.substr(4));
console.log(str.substr(-6));
console.log(str.substr(4, -1));
indexOf
- 用于确定一个字符串在另一个字符串中第一次出现的位置,返回结果是匹配开始的位置。如果返回-1,就表示不匹配。
function kmp(target, pattern) {
function prefix_table(pattren, prefix, n) {
prefix[0] = 0;
let len = 0;
let i = 1;
while (i < n) {
if(pattren[i] == pattren[len]) {
len++;
prefix[i] = len;
i++;
}else {
if(len > 0) {
len = prefix[len-1];
}else {
prefix[i] = len;
i++;
}
}
}
}
function move_prefix_table(prefix, n){
let i=0;
for(i=n-1;i>0;i--) {
prefix[i] = prefix[i-1];
}
prefix[0] = -1;
}
return function () {
let n = pattern.length;
let m = target.length;
const prefix = new Array(m).fill(0);
prefix_table(pattern, prefix, n);
move_prefix_table(prefix, n);
let i=0;
let j=0;
while(i < m) {
if(j == n-1 && target[i] == pattern[j]) {
return i-j;
}
if(target[i] == pattern[j]) {
i++;
j++;
}else {
j = prefix[j];
if(j==-1) {
i++;
j++;
}
}
}
return -1;
}
}
String.prototype.indexOf = function() {
let start = 0;
let end = 0;
if(arguments.length === 1) {
const pattern = arguments[0];
const target = this.return_all();
return kmp(target, pattern)();
}else if(arguments.length == 2) {
let start = arguments[1];
let end = this.length;
let st = this.return_sub(start, end);
const index = kmp(st, arguments[0])();
if(index < 0) {
return -1;
}else {
return index + start;
}
}
}
console.log( str.indexOf('Java') );
console.log( str.indexOf('Sc') );
console.log( str.indexOf('script') );
console.log( str.indexOf('i', 6) );
lastIndexOf
trim
- trim方法用于去除字符串两端的空格,返回一个新字符串,不改变原字符串。
- 方法去除的不仅是空格,还包括制表符(\t、\v)、换行符(\n)和回车符(\r)。
String.prototype.trim = function() {
let start = 0;
let end = this.length-1;
let arr = [' ', '\t', '\v', '\n', '\r']
while(arr.indexOf(this[start]) != -1) {
start++;
}
while(arr.indexOf(this[end]) != -1) {
end--;
}
end++;
return this.return_sub(start, end);
}
var str1 = new String(' JavaScript \t');
var str1 = new String('\r\nabc \t');
console.log(str1.trim())