js常用方法和一些封裝(1)

博主在js上已經(jīng)花費(fèi)了很長(zhǎng)時(shí)間,不禁深深地被其輕巧而強(qiáng)大的功能,以及優(yōu)雅靈活的寫(xiě)法所折服,一直沒(méi)找到機(jī)會(huì)來(lái)總結(jié)一下,最近發(fā)現(xiàn)了簡(jiǎn)書(shū)這個(gè)不錯(cuò)的平臺(tái),正好把學(xué)習(xí)的東西做一個(gè)匯總。

題外話

我始終認(rèn)為,學(xué)習(xí)編程最好的方式就是去寫(xiě),甭管寫(xiě)的怎樣,也要去練習(xí)。

當(dāng)初學(xué)完了數(shù)組,我記得自己是先把里面的每一個(gè)方法都敲了一遍,然后反復(fù)思考,通過(guò)這些方法,我能夠做些什么?

很多語(yǔ)法我一開(kāi)始也是很不理解的,然而在不斷地運(yùn)用過(guò)程中,慢慢地就開(kāi)始明白過(guò)來(lái)了。只要抓住一個(gè)大方向,然后不斷地練,就一定能深入理解!

正如國(guó)外一個(gè)有名的數(shù)學(xué)家所言,只有抓住了主樹(shù)干,枝葉方面的細(xì)節(jié)便會(huì)奇跡般地豐富起來(lái)。

很多初學(xué)者,包括當(dāng)年的我自己,總是覺(jué)得這個(gè)也要學(xué),那個(gè)也要學(xué),不敢直接去找工作,總想著全部學(xué)完了才行。可是呢,怎樣算是個(gè)頭呢,技術(shù)這東西日新月異。css3來(lái)了,一股腦兒跑去學(xué)css3,后來(lái)各種框架如雨后春筍般破土而出,ext.js,easy-ui,bootstrap,等等,面對(duì)各種各樣的新框架,真的感覺(jué)時(shí)間不夠。

其實(shí),現(xiàn)在我個(gè)人感覺(jué)真不必這樣,要知道,所有的js框架都是以js為源頭,當(dāng)自己js的功底足夠牢固,那么就一切OK。我之前認(rèn)識(shí)的一個(gè)朋友,從來(lái)沒(méi)接觸過(guò)bootstrap,后來(lái)公司要用,看了兩三天直接就上手,用bootstrap來(lái)開(kāi)發(fā)項(xiàng)目了。

js + css是根,真是如此的。

否則,你永遠(yuǎn)會(huì)覺(jué)得自己在學(xué)習(xí),卻不知道這樣的目的是什么。所以,不管三七二十一,如果你現(xiàn)在還是一個(gè)處于迷茫求職階段的畢業(yè)生,或者是剛培訓(xùn)完,那么,不用慌,先找一份工作干起來(lái)再說(shuō),在工作中慢慢積累。

不要害怕,覺(jué)得自己好多不懂,會(huì)不會(huì)有問(wèn)題,真沒(méi)關(guān)系的,不要企圖把所有技術(shù)學(xué)完了再去找工作。

哈,閑話不多說(shuō),開(kāi)始記錄。

1.字符串相關(guān)

1.1 format方法

在各種編程語(yǔ)言中,字符串的format方法是比較常見(jiàn)的,以下通過(guò)js擴(kuò)展的方式,實(shí)現(xiàn)了js版本的format方法。目前貌似還沒(méi)有瀏覽器支持這一個(gè)方法。

if(!String.prototype.format ){
    String.prototype.format = function() {
        var e = arguments;
        return this.replace(/{(\d+)}/g,function(t, n) {
            return typeof e[n] != "undefined" ? e[n] : t;
        })
    };
}

例子:

var template = "今天的天氣很{0},大家一起去{1}!";
alert(template.format("晴朗","郊游"));

效果:

Paste_Image.png

2.數(shù)組相關(guān)

1.2 forEach(callback,context) 操作數(shù)組中的每一個(gè)元素

ie9以上的瀏覽器,以及其他非IE瀏覽器都支持這一方法。
以下是兼容性的擴(kuò)展寫(xiě)法:

/**
    forEach除了接受一個(gè)必須的回調(diào)函數(shù)參數(shù),還可以接受一個(gè)可選的上下文參數(shù)(改變回調(diào)函數(shù)里面的this指向)(第2個(gè)參數(shù))。
*/
if (!Array.prototype.forEach && typeof Array.prototype.forEach !== "function") {
    Array.prototype.forEach = function(callback, context) {
       // 遍歷數(shù)組,在每一項(xiàng)上調(diào)用回調(diào)函數(shù),這里使用原生方法驗(yàn)證數(shù)組。
       if (Object.prototype.toString.call(this) === "[object Array]") {
           var i,len;
           //遍歷該數(shù)組所有的元素
           for (i = 0, len = this.length; i < len; i++) {
               if (typeof callback === "function"  && Object.prototype.hasOwnProperty.call(this, i)) {
                   if (callback.call(context, this[i], i, this) === false) {
                       break; // or return;
                   }
               }
           }
       }
    };
}

例子:

var drinks = ['雪碧','可樂(lè)','脈動(dòng)','紅牛','農(nóng)夫山泉'];
        
var context = {
    str1 : '【',
    str2 : '】'
};
        
drinks.forEach(function(item){
    console.log(this.str1 + item + this.str2);
},context);

效果:

Paste_Image.png

這個(gè)方法在各大瀏覽器都得到了較好的支持。

1.3 indexOf(searchvalue,fromindex) 查詢數(shù)組中某一個(gè)值的下標(biāo)

ie9以上的瀏覽器,以及其他非IE瀏覽器都支持這一方法。以下是兼容性的擴(kuò)展寫(xiě)法:

//獲取某元素在數(shù)組中第一次出現(xiàn)的下標(biāo)
if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function(searchElement, fromIndex) {
    var k;
    // 1. Let O be the result of calling ToObject passing
    //    the this value as the argument.
    if (this == null) {
      throw new TypeError('"this" is null or not defined');
    }

    var O = Object(this);

    // 2. Let lenValue be the result of calling the Get
    //    internal method of O with the argument "length".
    // 3. Let len be ToUint32(lenValue).
    var len = O.length >>> 0;

    // 4. If len is 0, return -1.
    if (len === 0) {
      return -1;
    }

    // 5. If argument fromIndex was passed let n be
    //    ToInteger(fromIndex); else let n be 0.
    var n = +fromIndex || 0;

    if (Math.abs(n) === Infinity) {
      n = 0;
    }

    // 6. If n >= len, return -1.
    if (n >= len) {
      return -1;
    }

    // 7. If n >= 0, then Let k be n.
    // 8. Else, n<0, Let k be len - abs(n).
    //    If k is less than 0, then let k be 0.
    k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);

    // 9. Repeat, while k < len
    while (k < len) {
      // a. Let Pk be ToString(k).
      //   This is implicit for LHS operands of the in operator
      // b. Let kPresent be the result of calling the
      //    HasProperty internal method of O with argument Pk.
      //   This step can be combined with c
      // c. If kPresent is true, then
      //    i.  Let elementK be the result of calling the Get
      //        internal method of O with the argument ToString(k).
      //   ii.  Let same be the result of applying the
      //        Strict Equality Comparison Algorithm to
      //        searchElement and elementK.
      //  iii.  If same is true, return k.
          if (k in O && O[k] === searchElement) {
            return k;
          }
          k++;
        }
        return -1;
      };
    }

例子:

var index = drinks.indexOf('雪碧');
alert(index);//0

類似的還有l(wèi)astIndexOf,用于獲取數(shù)組中某個(gè)元素最后一次出現(xiàn)的位置。如果數(shù)組沒(méi)有這個(gè)元素,則返回-1。順便貼上該方法的實(shí)現(xiàn):

//獲取某元素在數(shù)組中最后一次出現(xiàn)的下標(biāo)
if (!Array.prototype.lastIndexOf) {
      Array.prototype.lastIndexOf = function(searchElement /*, fromIndex*/) {
    'use strict';

    if (this === void 0 || this === null) {
      throw new TypeError();
    }

    var n, k,
        t = Object(this),
        len = t.length >>> 0;
    if (len === 0) {
      return -1;
    }

    n = len - 1;
    if (arguments.length > 1) {
      n = Number(arguments[1]);
      if (n != n) {
        n = 0;
      }
      else if (n != 0 && n != (1 / 0) && n != -(1 / 0)) {
        n = (n > 0 || -1) * Math.floor(Math.abs(n));
      }
    }

    for (k = n >= 0
          ? Math.min(n, len - 1)
          : len - Math.abs(n); k >= 0; k--) {
      if (k in t && t[k] === searchElement) {
        return k;
      }
    }
    return -1;
  };
}

通過(guò)這兩個(gè)方法,我們可以來(lái)做一些有意思的事情了。
比如,判斷一個(gè)對(duì)象是否為數(shù)組?

IE9 以上的瀏覽器,已經(jīng)支持通過(guò)Array.isArray()來(lái)驗(yàn)證一個(gè)對(duì)象是否為數(shù)組了。

比如:

var result = Array.isArray([]);
alert(typeof []);//object
alert(result); //true

那么,如果我們自己來(lái)實(shí)現(xiàn),又該如何做呢?下面給出一個(gè)簡(jiǎn)單思路,簡(jiǎn)單模擬一下這個(gè)過(guò)程:

//首先,讓我們來(lái)看一看數(shù)組的構(gòu)造器是咋樣的?
console.log([].constructor.toString());

/*
    打印出來(lái)是這樣的:
    function Array() { [native code] }
*/

于是乎。。。


var Array = function(){

}

Array.isArray = function(obj){
    return obj.constructor.toString().indexOf('Array') != -1;
}

var result = Array.isArray([]); 
alert(result); //true

雖然取巧了點(diǎn),不過(guò)目的確實(shí)達(dá)到了。

數(shù)組封裝

通過(guò)數(shù)組的一些基本方法,我們可以開(kāi)始自己模擬一下java中的ArrayList了,話不多說(shuō),貼上代碼:

//模擬ArrayList
function ArrayList(){
    var arr = []; //用于保存數(shù)據(jù)的數(shù)組
    var length = 0; //數(shù)組的長(zhǎng)度,默認(rèn)為0
    
    /**
     * 判斷是否為空
     */
    this.isEmpty = function(){
        return length == 0;
    }
    
    /**
     * 獲取列表長(zhǎng)度
     */
    
    this.size = function(){
        return length;
    }
    
    /** 
    * 判斷對(duì)象中是否包含給定對(duì)象
    */ 
    this.contains = function(obj){
        if(arr.indexOf(obj) != -1){
            return true;
        }
        return false;
    }
    
    /** 
    * 新增
    */
   this.add = function(obj){
    length = length + 1;
    arr.push(obj);
   }
   
   /**
    * 刪除
    * 參數(shù)1  obj : 需要?jiǎng)h除的元素
    * 參數(shù)2  deleteAll: 是否全部刪除,否則默認(rèn)刪除第一個(gè)匹配項(xiàng)
    */
   this.remove = function(obj,deleteAll){
        var len = arr.length;
        for(var i = 0 ;i < len ;i++){
            if(arr[i] == obj){
                arr.splice(i,1);
                length = length - 1;
                if(!deleteAll){
                    break;
                }
            }
        }
   }
   
   
   /**
    * 根據(jù)索引獲取對(duì)應(yīng)的元素
    */
   this.get = function(index){
    if(index > length - 1){
        return null;
    }
    return arr[index];
   }
   
   /**
    * 獲取列表數(shù)組
    */
   this.toArray = function(){
     return arr;
   }
   
   /**
    * 獲取某一個(gè)元素的角標(biāo)
    * 如果只出現(xiàn)一次,就返回一個(gè)數(shù)字,如果大于一次,就返回?cái)?shù)組
    */
   this.indexOf = function(obj){
     var rstArr = [];
     var count = 0;
     for(var i = 0 ;i < length ;i++){
        if(obj == arr[i]){
            rstArr[count++] = i;
        }
     }
     if(count == 1){
        return rstArr[0];
     }
     return rstArr;
   }
   
   this.toString = function(){
    return arr.toString();  
   }
}

//測(cè)試代碼
var list = new ArrayList();
list.add('張三');
list.add('李四');
list.add('王五');
list.add('趙六');
list.add('王五');
console.log(list.size());
console.log(list.toString());
console.log(list.contains('張三'));
list.remove('王五',true); //null,undefined,''
console.log(list.toString());
console.log(list.get(0));
console.log(list.get(1));
console.log(list.get(2));
console.log(list.size());

console.log(list.toArray());
list.add('張三');
list.add('張三');
console.log(list.toArray());
console.log(list.indexOf('張三'));
console.log(list.indexOf('趙六'));

運(yùn)行結(jié)果:

Paste_Image.png

本章結(jié)束 ...

剽悍一小兔,電氣自動(dòng)化畢業(yè)。
參加工作后對(duì)計(jì)算機(jī)感興趣,深知初學(xué)編程之艱辛。
希望將自己所學(xué)記錄下來(lái),給初學(xué)者一點(diǎn)幫助。

免責(zé)聲明: 博客中所有的圖片素材均來(lái)自百度搜索,僅供學(xué)習(xí)交流,如有問(wèn)題請(qǐng)聯(lián)系我,侵立刪,謝謝。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,991評(píng)論 19 139
  • Swift版本點(diǎn)擊這里歡迎加入QQ群交流: 594119878最新更新日期:18-09-17 About A cu...
    ylgwhyh閱讀 25,572評(píng)論 7 249
  • 問(wèn)答題47 /72 常見(jiàn)瀏覽器兼容性問(wèn)題與解決方案? 參考答案 (1)瀏覽器兼容問(wèn)題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)...
    _Yfling閱讀 13,814評(píng)論 1 92
  • TextView中可以設(shè)置一個(gè)ellipsize屬性,作用是當(dāng)文字長(zhǎng)度超過(guò)textview寬度時(shí)的顯示方式: 例如...
    NeWolf閱讀 12,206評(píng)論 0 1
  • 一這一天 今天是陽(yáng)光明媚的一天,他一如既往的提前上班,打開(kāi)辦公室的門(mén)開(kāi)始進(jìn)入工作狀態(tài),他的辦公室如曾經(jīng)的每一天一樣...
    闌十三閱讀 711評(píng)論 2 12