Posted in Javascript onJuly 16, 2012
(function(win) { var toString = Object.prototype.toString; var hasOwn = Object.prototype.hasOwnProperty; var class2type = {}; class2type["[object Boolean]"] = "boolean"; class2type["[object Number]"] = "number"; class2type["[object String]"] = "string"; class2type["[object Function]"] = "function"; class2type["[object Array]"] = "array"; class2type["[object Date]"] = "date"; class2type["[object RegExp]"] = "regexp"; class2type["[object Object]"] = "object"; win.type = function(obj) { return obj == null ? String(obj) : class2type[toString.call(obj)] || "object"; }; win.isBoolean = function(obj) { return type(obj) === "boolean"; }; win.isNumber = function(obj) { return type(obj) === "number"; }; win.isString = function(obj) { return type(obj) === "string"; }; win.isDate = function(obj) { return type(obj) === "date"; }; win.isRegExp = function(obj) { return type(obj) === "regexp"; }; win.isObject = function(obj) { return type(obj) === 'object'; }; win.isFunction = function(obj) { return type(obj) === "function"; }; win.isArray = function(obj) { return type(obj) === "array"; }; win.isWindow = function(obj) { return obj && typeof obj === "object" && "setInterval" in obj; }; win.isNumeric = function(obj) { return !isNaN(parseFloat(obj)) && isFinite(obj); }; win.isPlainObject = function(obj) { if (!obj || type(obj) !== "object" || obj.nodeType || isWindow(obj)) { return false; } try { if (obj.constructor && !hasOwn.call(obj, "constructor") && !hasOwn.call(obj.constructor.prototype, "isPrototypeOf")) { return false; } } catch (e) { return false; } var key; for (key in obj) { } return key === undefined || hasOwn.call(obj, key); }; win.isEmptyObject = function(obj) { for ( var name in obj) { return false; } return true; }; win.isPrimitive = function(obj){ var type = typeof obj; return type === 'string' || type === 'number' || type === 'boolean'; }; //HTMLElement win.isElement = function(obj){ return obj ? obj.nodeType === 1 : false; }; //TextNode win.isTextNode = function(obj){ return obj ? obj.nodeName === "#text" : false; }; win.isIterable = function(obj){ return (obj && typeof obj !== 'string') ? obj.length !== undefined : false; }; win.isDefined = function(obj){ return typeof obj !== 'undefined'; }; win.error = function(msg) { throw new Error(msg); }; win.now = function() { return (new Date()).getTime(); }; win.print = function(value) { document.write(value); }; win.println = function(value) { print(value); document.write("<br/>"); }; win.each = function(object, callback, args) { var name, i = 0, length = object.length, isObj = (length === undefined || isFunction(object)); if (args) { if (isObj) { for (name in object) { if (callback.apply(object[name], args) === false) { break; } } } else { for (; i < length;) { if (callback.apply(object[i++], args) === false) { break; } } } } else { if (isObj) { for (name in object) { if (callback.call(object[name], name, object[name]) === false) { break; } } } else { for (; i < length;) { if (callback.call(object[i], i, object[i++]) === false) { break; } } } } return object; }; win.Array.prototype.toString = function(){ return "[" + this.join() + "]" } win.extend = function() { var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {}, i = 1, length = arguments.length, deep = false; // Handle a deep copy situation if ( typeof target === "boolean" ) { deep = target; target = arguments[1] || {}; // skip the boolean and the target i = 2; } // Handle case when target is a string or something (possible in deep copy) if ( typeof target !== "object" && !isFunction(target) ) { target = {}; } // extend jQuery itself if only one argument is passed if ( length === i ) { target = this; --i; } for ( ; i < length; i++ ) { // Only deal with non-null/undefined values if ( (options = arguments[ i ]) != null ) { // Extend the base object for ( name in options ) { src = target[ name ]; copy = options[ name ]; // Prevent never-ending loop if ( target === copy ) { continue; } // Recurse if we're merging plain objects or arrays if ( deep && copy && ( isPlainObject(copy) || (copyIsArray = isArray(copy)) ) ) { if ( copyIsArray ) { copyIsArray = false; clone = src && isArray(src) ? src : []; } else { clone = src && isPlainObject(src) ? src : {}; } // Never move original objects, clone them target[ name ] = extend( deep, clone, copy ); // Don't bring in undefined values } else if ( copy !== undefined ) { target[ name ] = copy; } } } } // Return the modified object return target; }; })(window);
如果我们不用extend方法,可以象下面的方式写自己的组件:
(function(win){ win.StringBuffer = function(){ this.datas = []; } var proto = StringBuffer.prototype; proto.append = function(value){ this.datas.push(value); }, proto.toString = function(){ return this.datas.join(""); } })(window);
如果使用extend方法,可以象下面这样写组件:
(function(win){ win.extend(win,{ StringBuilder : function(){ this.datas = []; } }); win.extend(StringBuilder.prototype, { append : function(value){ this.datas.push(value); }, toString : function(){ return this.datas.join(""); } }); })(window);
两种方法的效果一样,但是extend方法还可以做更多事件,比如插件式开发,跟第二种方式很象。
当然,如果你本来就想写jQuery插件,那就直接用jQuery的extend就可以啦。
写自已的js类库需要的核心代码
声明:登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。
Reply on: @reply_date@
@reply_contents@