zoukankan      html  css  js  c++  java
  • javascript 超级字符串对象


    javascript 超级字符串对象

    基于不对原生对象进行扩展的原则,搞了这个方便的处理字符串的对象。

    下面是第一类工厂,相当于mootools的Native方法。

    var dom = {},//命名空间
    slice = Array.prototype.slice;
    dom.mixin = function (obj, bag) {
      if (arguments.length === 1) {
        bag = obj;
        obj = this;
      };
      if (obj && bag && typeof bag === 'object') {
        for (var p in bag) {
          if(bag.hasOwnProperty(p))
            obj[p] = bag[p];
        }
      };
      if (!+"v1") {//IE不能在for...in循环中遍历toString与valueOf属性,需要单独处理
        var t = bag.toString,v = bag.valueOf,op = Object.prototype;
        if (bag.hasOwnProperty("toString") && typeof t === "function" && t !== op.toString)
          obj.toString = t;
        if (bag.hasOwnProperty("valueOf") && typeof v === "function" && v !== op.valueOf)
          obj.valueOf = v;
      }
      return obj;
    };
    dom.factory = function(obj){//第一类工厂
      var init = obj.init,
      klass = function() {
        //如果传入参数与当前类是同一类型,则直接返回
        if(arguments.length === 1 && arguments[0] instanceof klass)
          return arguments[0];
        return new klass.fn.init(arguments);
      }
      klass.fn = klass.prototype = {
        init :init,
        constructor: klass
      };
      klass.fn.init.prototype = klass.fn;
      delete obj.klass;delete obj.init;
      dom.mixin(klass.fn, obj);
      //用于扩展原型方法
      klass.mixin = function(bag){
        dom.mixin(this.fn,bag);
        return this;
      };
      klass.alias = function(oldName, newName){
        var bag = {};
        if (dom.isString(oldName) && dom.isString(newName)){
          var method = this.fn[oldName]
          if (!!method){
            bag[newName] = method;
            return this.mixin(bag);
          };
        };
        //如果是一个属性包,如Hash.alias({keyOf: 'indexOf', hasValue: 'contains'});
        bag = oldName;
        for (var name in bag)
          if(bag.hasOwnProperty(name))
            this.alias(name,bag[name]);
        return this;
      };
      klass.staticizeWithout = function(arr){
        var conditions = {},keys = arr || [],me = this;
        for(var i=0,n = keys.length;i<n;i++){
          conditions[keys[i]] = 1;
        }
        dom.each(me.fn,function(method, name){
          if(!conditions[name] && dom.isFunction(me.fn[name]) && dom.isUndefined(me[name])&&
            name !== 'init' && name !== 'toString' && name !== 'valueOf' ){
            me[name] = function () {
              var args = dom.toArray(arguments),
              caller = args.shift();
              method.name = name; //为其泛化方法添加一个name属性
              return method.apply(me(caller), args);
            }
          }
        });
        return me;
      }
      return klass;
    };
    dom.mixin(new function(){
      var _toString = Object.prototype.toString,
      _slice = Array.prototype.slice,
      _push = Array.prototype.push,
      is = function(obj,type) {
        return _toString.call(obj).match(/^[objects(.*)]$/)[1] === type;
      }
      return {
        isArray: function (obj) {
          return is(obj,"Array");
        },
        isFunction: function (obj) {
          return is(obj,"Function") ;
        },
        isNumber: function (obj) {
          return is(obj,"Number") ;
        },
        isString: function (obj) {
          return is(obj,"String") ;
        },
        isUndefined: function (obj) {
          return  obj === void(0);
        },
        each: function (obj, fn, bind) {
          for (var key in obj) //只遍历本地属性
            if (obj.hasOwnProperty(key))
              fn.call(bind, obj[key], key, obj);
        },
        isArrayLike : function (obj) {//包括Array
          if(dom.isArray(obj) || obj.callee) return true;
          if(is(obj,'NodeList')) return true;
          if(is(obj,'HTMLCollection')) return true;
          //不能为字符串,不能为window,具有length属性
          if(dom.isNumber(obj.length) && !dom.isString(obj) && !obj.eval){
            if(obj.nextNode || obj.item)
              return true;
            var n = obj.length - 1 < 0 ? 0 : obj.length - 1 ;
            //如果是具有数字键或length属性的对象,如jQuery对象
            if(obj.hasOwnProperty(n) && obj.hasOwnProperty(0))
              return true
            return false;
          }
          return false;
        },
        toArray : function (arr) { //把普通对象变成原生数组对象
          if(arguments.length === 0 || arr === null){
            return [];
          }else if(arr.callee){//如果是Arguments对象
            return _slice.call(arr);
          }else if(dom.isArray(arr)){//如果Array对象返回一个克隆
            return arr.concat();
          }else if(dom.isArrayLike(arr)){
            try{//jQuery对象,dom对象,el.getElementsByTagName得到的HTMLCollection
              //与el.childNodes得到的NodeList
              return _slice.call(arr);
            }catch(e){//IE用slice处理元素或节点集合会出错,只能慢慢拷贝
              var ret = [], i = arr.length;
              while (i) ret[--i] = arr[i]; //Clone数组
              return ret;
            }
          }else {//普通函数,单个元素节点,字符串,数字,window对象
            return [arr];
          }
        },
        setArray: function (els) { //把普通对象变成类数组对象
          this.length = 0;
          _push.apply(this, els);
          return this;
        }
      }
    });
    dom.win = window;

    类工厂的能力很强大,生成的类拥有自我扩展的能力。下面是超级字符串的核心方法,分别为入口函数,构造函数,toString,valueOf与一个重要的setArray方法,用于设置charAt的索引值与length属性。

    var string = dom.factory({
      init: function (obj) {
        this.setArray(obj[0].split(''));
        return this;
      },
      toString: function () {
        return this.valueOf();
      },
      valueOf: function () {
        return Array.prototype.join.call(this, '');
      },
      setArray: dom.setArray
    });

    再把字符串的泛化方法加持到其上,让其伪装成字符串对象。

    //为超级字符串对象添加原生字符串对象的泛化方法
    dom.each("charAt,charCodeAt,concat,indexOf,lastIndexOf,match,
            replace,search,slice,split,substr,substring,toLowerCase,
            toUpperCase,fontcolor,big,small,anchor,link,bold,italics,
            sub,sup,fixed,fontsize,strike".match(/w+/g),
    function (name) {
      string.fn[name] = function () {
        var method = String.prototype[name],
        args = dom.toArray(arguments),
        ret = method.apply(this.valueOf(), args);
        if (dom.isString(ret))
          return string(ret)
        return ret;
      }
    });

    全局变量window也有许多专门处理字符串的方法,我们也把它们加持到超级字符串对象上。

    //为超级字符串对象添加全局对象处理字符串的相关方法
    dom.each("parseInt,parseFloat,escape,unescape,eval,decodeURI,
            encodeURI,decodeURIComponent,encodeURIComponent".match(/w+/g),
    function (name) {
      string.fn[name] = function () {
        var ret = dom.win[name](this.valueOf());
        if (dom.isString(ret)) //确保返回超级字符串对象
          return string(ret);
        return ret;
      }
    });

    再添加一些有用的自定义方法:

    string.mixin({
      trim: function () {
        var str = this.valueOf();
        if (String.trim) {
          return string(String.trim(str))
        } else {
          str = str.replace(/^ss*/, '');
          var ws = /s/,
          i = str.length;
          while (ws.test(str.charAt(--i)));
          return string(str.slice(0, i + 1));
        };
      },
      dasherize: function () {
        return this.replace(/_/g, '-');
      },
      camelize : function (str) {
        return this.replace(/-([a-z])/g, function($1,$2){
          return $2.toUpperCase()
        });
      },
      capitalize: function () {
        return this.replace(/S+/g, function ($1) {
          return $1.charAt(0).toUpperCase() + $1.slice(1);
        });
      },
      contains: function (segment) {
        return this.indexOf(segment) !== -1;
      },
      startsWith: function (pattern) {
        return this.indexOf(pattern) === 0;
      },
      endsWith: function (pattern) {
        var d = this.length - pattern.length;
        return d >= 0 && this.lastIndexOf(pattern) === d;
      },
      empty: function () {
        return this.valueOf() === '';
      },
      blank: function () {
        return /^s*$/.test(this.valueOf());
      },
      times: function (n) {
        if (n == 1)
          return this;
        var s = this.times(Math.floor(n / 2));
        s += s;
        if (n % 2) {
          s += this;
        }
        return string(s);
      }
    });
    //静态化超级字符串对象的大部分原型方法
    string.staticizeWithout(["setArray"]);
    dom.string = string;

    像字符串原有的方法与window处理字符串的相关方法就不废话了,我们看一下自定义方法的用法。

    超级字符串对象
    trim 去除左右两边的空白
    contains 检测string是否包含给定的子串
    dasherize 将字符串中的"_"代替成"-"
    camelize 将字符串改成驼峰风格
    capitalize 首字符大写
    startsWith 检测string以给定的子串开头
    endsWith 检测string以给定的子串结束
    empty 检测string是否一个字符也没有
    blank 检测string是否全部由空白字符构成
    times 字符串乘法,传入一个数字,作为原字符串的倍数

    相关链接:超级数组对象

    为人:谦逊、激情、博学、审问、慎思、明辨、 笃行
    学问:纸上得来终觉浅,绝知此事要躬行
    为事:工欲善其事,必先利其器。
    态度:道阻且长,行则将至;行而不辍,未来可期
    转载请标注出处!
  • 相关阅读:
    IE和FF下面的css半透明效果
    javascript 文字滚动
    利用URLRewriter重写url
    “/”应用程序中的服务器错误。
    Iframe 参数列表
    【转】CSS的一些技巧
    ASP.NET 如何动态修改 title Meta link标签
    Test2.数据库批处理添加练习(mysql_java)
    html5(test1.提交表单)
    smartupload图片上传
  • 原文地址:https://www.cnblogs.com/ios9/p/14768755.html
Copyright © 2011-2022 走看看