现在的位置: 首页 > 综合 > 正文

写自已的类库需要的核心代码

2012年10月31日 ⁄ 综合 ⁄ 共 4403字 ⁄ 字号 评论关闭

众所周知,用jQuery的extend方法,可以很方便的实现继承和对象拷贝,我们可以把它拿过来自己用。

(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就可以啦。

抱歉!评论已关闭.