javascript 超級字符串對象 javascript 超級字符串對象


javascript 超級字符串對象

基於不對原生對象進行擴展的原則,搞了這個方便的處理字符串的對象。javascript

下面是第一類工廠,至關於mootools的Native方法。java

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(/^\[object\s(.*)\]$/)[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屬性。api

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也有許多專門處理字符串的方法,咱們也把它們加持到超級字符串對象上。app

//爲超級字符串對象添加全局對象處理字符串的相關方法
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;
  }
});

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

string.mixin({
  trim: function  () {
    var str = this .valueOf();
    if  (String.trim) {
      return  string(String.trim(str))
    } else  {
      str = str.replace(/^\s\s*/, '' );
      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;

運行代碼ide

像字符串原有的方法與window處理字符串的相關方法就不廢話了,咱們看一下自定義方法的用法。函數

超級字符串對象
trim 去除左右兩邊的空白
contains 檢測string是否包含給定的子串
dasherize 將字符串中的"_"代替成"-"
camelize 將字符串改爲駝峯風格
capitalize 首字符大寫
startsWith 檢測string以給定的子串開頭
endsWith 檢測string以給定的子串結束
empty 檢測string是否一個字符也沒有
blank 檢測string是否所有由空白字符構成
times 字符串乘法,傳入一個數字,做爲原字符串的倍數

相關連接:超級數組對象this

爲人:謙遜、激情、博學、審問、慎思、明辨、 篤行 學問:紙上得來終覺淺,絕知此事要躬行 爲事:工欲善其事,必先利其器。 轉載請標註出處!
相關文章
相關標籤/搜索