js原生api之String的slice方法


  我們在工作中可能會很少進行這樣的思考,對於一些常用的原生api它是如何實現的呢,如果讓我們去用js實現一個與原生api功能相同的函數我們該如何設計算法去實現呢? 

  為了鞏固自己的編程技術和提高自己的編程技巧,也為了讓自己對js這門語言有更深刻的理解,我將會把平時開發常用到的各種原生api用自己的方式去實現,如果有錯誤的地方或者代碼運行效率有更好的實現方案歡迎大神指正和批評 

  本次將要實現的第一個方法是Javascript的String基本類型和String對象的常用方法 slice 

  slice的定義和用法 (紅色文字部分摘自菜鳥教程,slice方法)

slice(start, end) 方法可提取字符串的某個部分,並以新的字符串返回被提取的部分。

使用 start(包含) 和 end(不包含) 參數來指定字符串提取的部分。

字符串中第一個字符位置為 0, 第二個字符位置為 1, 以此類推。

提示: 如果是負數,則該參數規定的是從字符串的尾部開始算起的位置。也就是說,-1 指字符串的最后一個字符,-2 指倒數第二個字符,以此類推。 

start:必須. 要抽取的片斷的起始下標。第一個字符位置為 0 

end:可選。 緊接着要截取的片段結尾的下標。若未指定此參數,則要提取的子串包括 start 到原字符串結尾的字符串。

  如果該參數是負數,那么它規定的是從字符串的尾部開始算起的位置。 

  slice()方法在第一個參數為負數時不管第二個參數為正數還是負數都會返回"";第二個參數為負數時會將負的參數加上字符串的長度。 

 1 var sliceYMWM=function(s,start,end){
 2         // 首先我們的方法得滿足大前提,s必須為String類型或者是String對象的實例
 3         if(typeof(s) == 'string' || s instanceof String){
 4             var slen=s.length;
 5             var aglen=arguments.length;
 6             var res="";
 7             // 我們先處理只用兩個參數 s 和 start 的情況
 8             if(aglen==2){
 9                 if(start>slen){ //此時起始索引大於串長返回空串
10                     return res;
11                 }else if(start>0&&start<slen){
12                     for(let i = start; i<slen; i++){
13                         res+=s[i];
14                     }
15                     return res;
16                 }else{
17                     for(let q = slen+start; q<slen; q++){
18                         res+=s[q];
19                     }
20                     return res;
21                 }
22             }else if(aglen==3){//當三個參數都有的情況
23                 if(start<0){//第一個參數 start 為負數時,都會返回 ""
24                     return res;
25                 }else{
26                     if(end<0){ //當第三個參數 end 為負數時,需要加串長轉換成正序的索引
27                         if(start<end+slen){
28                             for(let j= start; j<end+slen;j++){
29                                 res+=s[j];
30                             }
31                             return res;
32                         }else{ //此時起始索引大於等於結束索引返回空串
33                             return res;
34                         }
35                     }else{ 
36                         if(start<end){ //當結束索引大於串長時,須改良循環結構的退出條件,否則當結束索引遠大於串長時會做無用的性能消耗
37                             if(end<slen){
38                                 for(let k=start; k<end;k++){
39                                     res+=s[k];
40                                 }
41                                 return res;
42                             }else{
43                                 for(let k=start; k<slen;k++){
44                                     res+=s[k];
45                                 }
46                                 return res;
47                             }
48                         }else{  //此時起始索引大於等於結束索引返回空串
49                             return res;
50                         }
51                     }
52                 }
53             }else{
54                 throw "參數個數不滿足要求!";
55             }
56         }else{
57             throw "傳入的s並非是字符串類型或者是字符串對象!";
58             
59         }
60     }
61     var s1=new String('倚夢為碼!');
62 var s1_=sliceYMWM(s1,0); //運行結果為 String {"倚夢為碼!"} 63 var s2='倚夢為碼!';
64 var s2_=sliceYMWM(s2,0); //運行結果為 "倚夢為碼!"
65  var s3_=sliceYMWM(s2,-2); // 運行結果為 "碼!"
66   var s4_=sliceYMWM(s2,1,-1) //運行結果為 "夢為碼"
 
總結:在用js進行實現slice方法時尤其要注意臨界值的判斷條件,不能少判斷也不能做多余的判斷防止算法出現與原生slice方法有結果不一致的情況,而且在進行循環條件時應盡量做到不對全局變量的屬性查找之類的操作,因為這種操作的時間復雜度為 O(n) 。

我們可以在第一次對全局變量進行屬性訪問時將其地址存到一個局部變量中,這樣的話只會在第一次進行操作時會對全局變量做屬性搜素,往后只需對局部變量進行訪問,這時算法復雜度只有 O(1),正所謂的即用即取。有興趣的小伙伴可以自己做做類似的練習。本文為作者  倚夢為碼  原創,歡迎大家觀看和轉載,若有其他用途請注明出處!謝謝合作!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM