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(/^\[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属性。
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(/^\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;
像字符串原有的方法与window处理字符串的相关方法就不废话了,我们看一下自定义方法的用法。
| 超级字符串对象 | |
|---|---|
| trim | 去除左右两边的空白 |
| contains | 检测string是否包含给定的子串 |
| dasherize | 将字符串中的"_"代替成"-" |
| camelize | 将字符串改成驼峰风格 |
| capitalize | 首字符大写 |
| startsWith | 检测string以给定的子串开头 |
| endsWith | 检测string以给定的子串结束 |
| empty | 检测string是否一个字符也没有 |
| blank | 检测string是否全部由空白字符构成 |
| times | 字符串乘法,传入一个数字,作为原字符串的倍数 |
相关链接:超级数组对象
机器瞎学/数据掩埋/模式混淆/人工智障/深度遗忘/神经掉线/计算机幻觉/专注单身二十五年
浙公网安备 33010602011771号