淘宝Kissy框架分析【四】
2010-06-15 12:00 BlueDream 阅读(3345) 评论(0) 收藏 举报今天开始分析kissy-lang.js
源码如下:
/**
* @module j1616-lang
* @author liangchaoyjs@163.com
*/
J1616.add('j1616.lang', function(J, undefined) {
var win = window, doc = document, loc = location,
AP = Array.prototype,
indexOf = AP.indexOf, filter = AP.filter,
trim = String.prototype.trim,
toString = Object.prototype.toString,
encode = encodeURIComponent,
decode = decodeURIComponent,
REG_TRIM = /^\s+|\s+$/g,
REG_ARR_KEY = /^(\w+)\[\]$/,
REG_NOT_WHITE = /\S/;
J.mix(J, {
isBoolean: function(o) {
return typeof o === 'boolean';
},
isString: function(o) {
return typeof o === 'string';
},
// infinity and NaN return false
isNumber: function(o) {
return typeof o === 'number' && isFinite(o);
},
// using {} or new Object();
isPlainObject: function(o) {
// Make sure that DOM nodes and window objects don't pass
return o && toString.call(o) === '[object Object]' && !o['nodeType'] && !o['setInterval'];
},
isEmptyObject: function(o) {
for (var p in o) {
return false;
}
return true;
},
isFunction: function(o) {
// safari typeof NodeList 也返回function
return toString.call(o) === '[object Function]';
},
isArray: function(o) {
return toString.call(o) === '[object Array]';
},
trim: trim ? function(str) {
return (str === undefined) ? '' : trim.call(str);
} : function(str) {
return (str === undefined) ? '' : str.toString().replace(REG_TRIM, '');
},
each: function(arr, fn, context) {
var l = (arr && arr.length) || 0, i = 0;
for (; i < l; ++i) {
fn.call(context || win, arr[i], i, arr);
}
},
indexOf: indexOf ?
function(elem, arr) {
return indexOf.call(arr, elem);
} :
function(elem, arr) {
for (var i = 0, len = arr.length; i < len; ++i) {
if (arr[i] === elem) {
return i;
}
}
return -1;
},
inArray: function(elem, arr) {
return J.indexOf(elem, arr) !== -1;
},
makeArray: function(o) {
if (o === null || o === undefined) return [];
if (J.isArray(o)) return o;
if (typeof o.length !== 'number' || typeof o === 'string' || J.isFunction(o)) {
return [o];
}
// ie不支持 slice 转换 Nodelist, 降级到普通方法
if (o.item && J.UA.ie) { //-------- 需要kissy-ua.js支持
var ret = [], i = 0, len = o.length;
for (; i < len; ++i) {
ret[i] = o[i];
}
return ret;
}
return AP.slice.call(o);
},
filter: filter ?
function(arr, fn, context) {
return filter.call(arr, fn, context);
} :
function(arr, fn, context) {
var ret = [];
J.each(arr, function(item, i, arr) {
if (fn.call(context, item, i, arr)) {
ret.push(item);
}
});
return ret;
},
param: function(o) {
if (!J.isPlainObject(o)) return '';
var buf = [], key, val;
for (key in o) {
val = o[key];
key = encode(key);
if (isValidParamValue(value)) {
buf.push(key, '=', encode(val + ''), '&');
}
else if (J.isArray(val) && val.length) {
for (var i = 0, len = val.length; i < len; ++i) {
if (isValidParamValue(val[i])) {
buf.push(key, '[]=', encode(val[i] + ''), '&');
}
}
}
}
buf.pop(); // 弹出最后多余的&
return buf.join('');
},
unparam: function(str, sep) {
if (typeof str !== 'string' || (str = J.trim(str)).length === 0) return {};
var ret = {},
pairs = str.split(sep || '&'),
pair, key, val, m,
i = 0, len = pairs.length;
for (; i < len; i++) {
pair = pairs[i].split('=');
key = decode(pair[0]);
// pair[1] 可能包含gbk编码中文, 而decodeURIComponent 仅能处理utf-8 编码中文
try {
val = decode(pair[1]);
} catch(e) {
val = pair[1] || '';
}
if ((m = key.match(REG_ARR_KEY)) && m[1]) {
ret[m[1]] = ret[m[1]] || [];
ret[m[1]].push(val);
} else {
ret[key] = val;
}
}
return ret;
},
later: function(fn, when, periodic, o, data) {
when = when || 0;
o = o || {};
var m = fn, d = J.makeArray(data), f, r;
if (typeof fn === 'string') {
m = o[fn];
}
if (!m) {
J.error('method undefined');
}
f = function() {
m.apply(o, d);
};
r = (periodic) ? setInterval(f, when) : setTimeout(f, when);
return {
id: r,
interval: periodic,
cancel: function() {
if (this.interval) {
clearInterval(r);
} else {
clearTimeout(r);
}
}
};
},
now: function() {
return new Date().getTime();
},
globalEval: function(data) {
if (data && REG_NOT_WHITE.test(data)) {
var head = doc.getElementsByTagName('head')[0] || doc,
script = doc.createElement('script');
script.text = data;
head.insertBefore(script, head.firstChild);
head.removeChild(script);
}
}
});
function isValidParamValue(val) {
var t = typeof val;
return val === null || (t !== 'object' && t !== 'function');
}
if (loc && loc.search && loc.search.indexOf('ks-debug') !== -1) {
J.Config.debug = true;
}
});
* @module j1616-lang
* @author liangchaoyjs@163.com
*/
J1616.add('j1616.lang', function(J, undefined) {
var win = window, doc = document, loc = location,
AP = Array.prototype,
indexOf = AP.indexOf, filter = AP.filter,
trim = String.prototype.trim,
toString = Object.prototype.toString,
encode = encodeURIComponent,
decode = decodeURIComponent,
REG_TRIM = /^\s+|\s+$/g,
REG_ARR_KEY = /^(\w+)\[\]$/,
REG_NOT_WHITE = /\S/;
J.mix(J, {
isBoolean: function(o) {
return typeof o === 'boolean';
},
isString: function(o) {
return typeof o === 'string';
},
// infinity and NaN return false
isNumber: function(o) {
return typeof o === 'number' && isFinite(o);
},
// using {} or new Object();
isPlainObject: function(o) {
// Make sure that DOM nodes and window objects don't pass
return o && toString.call(o) === '[object Object]' && !o['nodeType'] && !o['setInterval'];
},
isEmptyObject: function(o) {
for (var p in o) {
return false;
}
return true;
},
isFunction: function(o) {
// safari typeof NodeList 也返回function
return toString.call(o) === '[object Function]';
},
isArray: function(o) {
return toString.call(o) === '[object Array]';
},
trim: trim ? function(str) {
return (str === undefined) ? '' : trim.call(str);
} : function(str) {
return (str === undefined) ? '' : str.toString().replace(REG_TRIM, '');
},
each: function(arr, fn, context) {
var l = (arr && arr.length) || 0, i = 0;
for (; i < l; ++i) {
fn.call(context || win, arr[i], i, arr);
}
},
indexOf: indexOf ?
function(elem, arr) {
return indexOf.call(arr, elem);
} :
function(elem, arr) {
for (var i = 0, len = arr.length; i < len; ++i) {
if (arr[i] === elem) {
return i;
}
}
return -1;
},
inArray: function(elem, arr) {
return J.indexOf(elem, arr) !== -1;
},
makeArray: function(o) {
if (o === null || o === undefined) return [];
if (J.isArray(o)) return o;
if (typeof o.length !== 'number' || typeof o === 'string' || J.isFunction(o)) {
return [o];
}
// ie不支持 slice 转换 Nodelist, 降级到普通方法
if (o.item && J.UA.ie) { //-------- 需要kissy-ua.js支持
var ret = [], i = 0, len = o.length;
for (; i < len; ++i) {
ret[i] = o[i];
}
return ret;
}
return AP.slice.call(o);
},
filter: filter ?
function(arr, fn, context) {
return filter.call(arr, fn, context);
} :
function(arr, fn, context) {
var ret = [];
J.each(arr, function(item, i, arr) {
if (fn.call(context, item, i, arr)) {
ret.push(item);
}
});
return ret;
},
param: function(o) {
if (!J.isPlainObject(o)) return '';
var buf = [], key, val;
for (key in o) {
val = o[key];
key = encode(key);
if (isValidParamValue(value)) {
buf.push(key, '=', encode(val + ''), '&');
}
else if (J.isArray(val) && val.length) {
for (var i = 0, len = val.length; i < len; ++i) {
if (isValidParamValue(val[i])) {
buf.push(key, '[]=', encode(val[i] + ''), '&');
}
}
}
}
buf.pop(); // 弹出最后多余的&
return buf.join('');
},
unparam: function(str, sep) {
if (typeof str !== 'string' || (str = J.trim(str)).length === 0) return {};
var ret = {},
pairs = str.split(sep || '&'),
pair, key, val, m,
i = 0, len = pairs.length;
for (; i < len; i++) {
pair = pairs[i].split('=');
key = decode(pair[0]);
// pair[1] 可能包含gbk编码中文, 而decodeURIComponent 仅能处理utf-8 编码中文
try {
val = decode(pair[1]);
} catch(e) {
val = pair[1] || '';
}
if ((m = key.match(REG_ARR_KEY)) && m[1]) {
ret[m[1]] = ret[m[1]] || [];
ret[m[1]].push(val);
} else {
ret[key] = val;
}
}
return ret;
},
later: function(fn, when, periodic, o, data) {
when = when || 0;
o = o || {};
var m = fn, d = J.makeArray(data), f, r;
if (typeof fn === 'string') {
m = o[fn];
}
if (!m) {
J.error('method undefined');
}
f = function() {
m.apply(o, d);
};
r = (periodic) ? setInterval(f, when) : setTimeout(f, when);
return {
id: r,
interval: periodic,
cancel: function() {
if (this.interval) {
clearInterval(r);
} else {
clearTimeout(r);
}
}
};
},
now: function() {
return new Date().getTime();
},
globalEval: function(data) {
if (data && REG_NOT_WHITE.test(data)) {
var head = doc.getElementsByTagName('head')[0] || doc,
script = doc.createElement('script');
script.text = data;
head.insertBefore(script, head.firstChild);
head.removeChild(script);
}
}
});
function isValidParamValue(val) {
var t = typeof val;
return val === null || (t !== 'object' && t !== 'function');
}
if (loc && loc.search && loc.search.indexOf('ks-debug') !== -1) {
J.Config.debug = true;
}
});
1.isBoolean, isString, isNumber, isArray, isFunction类型判断函数
类型判断函数没啥可说基本类型可以用typeof 复制类型使用Object.prototype.toString.call()来监测.
注意:
(1).isNumber 如果是infinity或NaN应该返回false. 所以加了isFinite(o)来限制.
(2).isFunction由于在safari下typeof NodeList也返回function. 所以还是用toString.call来监测.
2. isPlainObject函数
作用: 检测一个Object是否由{}或new Object()创建.此版本比较简单.不能够防止{'nodeType':true}的hack.复杂的可以参考jQuery
3.isEmptyObject函数
作用: 检测一个对象是否为空对象.
4.trim函数
作用:去除字符串的作用空格.kissy用的是比较简洁的正则.有更快效率的trim.但为了简洁性.可以忽略ms的效率差.
5.each函数
作用:循环遍历数组.并调用回调函数. arr[i], i ,arr依次为回调函数的参数.
测试用例:
(function(J) {
J.each(['a', 'b', 'c', 'd'], function(item, index, arr) {
J.log(item + index); // a0, b1, c2, d3
});
})(J1616);
J.each(['a', 'b', 'c', 'd'], function(item, index, arr) {
J.log(item + index); // a0, b1, c2, d3
});
})(J1616);
6.indexOf函数
作用:检测一个元素在一个数组中是否存在.如果存在返回索引值.如果不存在则返回-1.
测试用例:
(function(J) {
J.log(J.indexOf('a', ['b', 'a', 'c'])); // 1
J.log(J.indexOf('a', ['b', 'c', 'd'])); // -1
})(J1616);
J.log(J.indexOf('a', ['b', 'a', 'c'])); // 1
J.log(J.indexOf('a', ['b', 'c', 'd'])); // -1
})(J1616);
7.inArray函数
作用:检测一个元素是否在数组中存在.如果存在返回true.否则返回false.
测试用例:
(function(J) {
J.log(J.inArray('a', ['a', 'b', 'c'])); // true
J.log(J.inArray('a', ['b', 'c', 'd'])); // false
})(J1616);
J.log(J.inArray('a', ['a', 'b', 'c'])); // true
J.log(J.inArray('a', ['b', 'c', 'd'])); // false
})(J1616);