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

博主在js上已经花费了很长时间,不禁深深地被其轻巧而强大的功能,以及优雅灵活的写法所折服,一直没找到机会来总结一下,最近发现了简书这个不错的平台,正好把学习的东西做一个汇总。

题外话

我始终认为,学习编程最好的方式就是去写,甭管写的怎样,也要去练习。

当初学完了数组,我记得自己是先把里面的每一个方法都敲了一遍,然后反复思考,通过这些方法,我能够做些什么?

很多语法我一开始也是很不理解的,然而在不断地运用过程中,慢慢地就开始明白过来了。只要抓住一个大方向,然后不断地练,就一定能深入理解!

正如国外一个有名的数学家所言,只有抓住了主树干,枝叶方面的细节便会奇迹般地丰富起来。

很多初学者,包括当年的我自己,总是觉得这个也要学,那个也要学,不敢直接去找工作,总想着全部学完了才行。可是呢,怎样算是个头呢,技术这东西日新月异。css3来了,一股脑儿跑去学css3,后来各种框架如雨后春笋般破土而出,ext.js,easy-ui,bootstrap,等等,面对各种各样的新框架,真的感觉时间不够。

其实,现在我个人感觉真不必这样,要知道,所有的js框架都是以js为源头,当自己js的功底足够牢固,那么就一切OK。我之前认识的一个朋友,从来没接触过bootstrap,后来公司要用,看了两三天直接就上手,用bootstrap来开发项目了。

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

否则,你永远会觉得自己在学习,却不知道这样的目的是什么。所以,不管三七二十一,如果你现在还是一个处于迷茫求职阶段的毕业生,或者是刚培训完,那么,不用慌,先找一份工作干起来再说,在工作中慢慢积累。

不要害怕,觉得自己好多不懂,会不会有问题,真没关系的,不要企图把所有技术学完了再去找工作。

哈,闲话不多说,开始记录。

1.字符串相关

1.1 format方法

在各种编程语言中,字符串的format方法是比较常见的,以下通过js扩展的方式,实现了js版本的format方法。目前貌似还没有浏览器支持这一个方法。

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.数组相关

1.2 forEach(callback,context) 操作数组中的每一个元素

ie9以上的浏览器,以及其他非IE浏览器都支持这一方法。
以下是兼容性的扩展写法:

/**
    forEach除了接受一个必须的回调函数参数,还可以接受一个可选的上下文参数(改变回调函数里面的this指向)(第2个参数)。
*/
if (!Array.prototype.forEach && typeof Array.prototype.forEach !== "function") {
    Array.prototype.forEach = function(callback, context) {
       // 遍历数组,在每一项上调用回调函数,这里使用原生方法验证数组。
       if (Object.prototype.toString.call(this) === "[object Array]") {
           var i,len;
           //遍历该数组所有的元素
           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 = ['雪碧','可乐','脉动','红牛','农夫山泉'];
        
var context = {
    str1 : '【',
    str2 : '】'
};
        
drinks.forEach(function(item){
    console.log(this.str1 + item + this.str2);
},context);

效果:

Paste_Image.png

这个方法在各大浏览器都得到了较好的支持。

1.3 indexOf(searchvalue,fromindex) 查询数组中某一个值的下标

ie9以上的浏览器,以及其他非IE浏览器都支持这一方法。以下是兼容性的扩展写法:

//获取某元素在数组中第一次出现的下标
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

类似的还有lastIndexOf,用于获取数组中某个元素最后一次出现的位置。如果数组没有这个元素,则返回-1。顺便贴上该方法的实现:

//获取某元素在数组中最后一次出现的下标
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;
  };
}

通过这两个方法,我们可以来做一些有意思的事情了。
比如,判断一个对象是否为数组?

IE9 以上的浏览器,已经支持通过Array.isArray()来验证一个对象是否为数组了。

比如:

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

那么,如果我们自己来实现,又该如何做呢?下面给出一个简单思路,简单模拟一下这个过程:

//首先,让我们来看一看数组的构造器是咋样的?
console.log([].constructor.toString());

/*
    打印出来是这样的:
    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

虽然取巧了点,不过目的确实达到了。

数组封装

通过数组的一些基本方法,我们可以开始自己模拟一下java中的ArrayList了,话不多说,贴上代码:

//模拟ArrayList
function ArrayList(){
    var arr = []; //用于保存数据的数组
    var length = 0; //数组的长度,默认为0
    
    /**
     * 判断是否为空
     */
    this.isEmpty = function(){
        return length == 0;
    }
    
    /**
     * 获取列表长度
     */
    
    this.size = function(){
        return length;
    }
    
    /** 
    * 判断对象中是否包含给定对象
    */ 
    this.contains = function(obj){
        if(arr.indexOf(obj) != -1){
            return true;
        }
        return false;
    }
    
    /** 
    * 新增
    */
   this.add = function(obj){
    length = length + 1;
    arr.push(obj);
   }
   
   /**
    * 删除
    * 参数1  obj : 需要删除的元素
    * 参数2  deleteAll: 是否全部删除,否则默认删除第一个匹配项
    */
   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;
                }
            }
        }
   }
   
   
   /**
    * 根据索引获取对应的元素
    */
   this.get = function(index){
    if(index > length - 1){
        return null;
    }
    return arr[index];
   }
   
   /**
    * 获取列表数组
    */
   this.toArray = function(){
     return arr;
   }
   
   /**
    * 获取某一个元素的角标
    * 如果只出现一次,就返回一个数字,如果大于一次,就返回数组
    */
   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();  
   }
}

//测试代码
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('赵六'));

运行结果:

Paste_Image.png

本章结束 ...

剽悍一小兔,电气自动化毕业。
参加工作后对计算机感兴趣,深知初学编程之艰辛。
希望将自己所学记录下来,给初学者一点帮助。

免责声明: 博客中所有的图片素材均来自百度搜索,仅供学习交流,如有问题请联系我,侵立删,谢谢。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,637评论 18 139
  • Swift版本点击这里欢迎加入QQ群交流: 594119878最新更新日期:18-09-17 About A cu...
    ylgwhyh阅读 25,339评论 7 249
  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,737评论 1 92
  • TextView中可以设置一个ellipsize属性,作用是当文字长度超过textview宽度时的显示方式: 例如...
    NeWolf阅读 12,078评论 0 1
  • 一这一天 今天是阳光明媚的一天,他一如既往的提前上班,打开办公室的门开始进入工作状态,他的办公室如曾经的每一天一样...
    阑十三阅读 672评论 2 12