Ruby's Louvre

每天学习一点点算法

导航

mass Framework lang模块 v4

本次升级引进一些非常有用的方法,去掉一些用户也能简单实现的方法。详细如下:

  • 字符串的blank, empty, toInt, toFloat方法, 它们被移到more/string模块中去。
  • Object.forEach方法去掉,取而代之是Object.each,数组也增加一个叫each方法。each方法不同于forEach,它可以通过回调返回false中断迭代。
  • 添加$.throttle与$.debounce,用于处理函数的调用频率。
  • 精简一下$.dump的方法代码量。
  • 添加stripTags,stripScripts,escapeHTML,unescapeHTML这四个在Prototype.js就赫赫有名的方法,专门用于处理用户输入输出。
  • padRight与padLeft在实现就是一行的差异,现在padRight是在内部调用padLeft实现。
  • 添加wbr字符串方法,对长字符进行换行,比如英文,数字在中文语句中不会断开,里面插入<wbr>就可以了。

地址:https://github.com/RubyLouvre/mass-Framework/blob/master/src/lang.js

//=========================================
// 类型扩展模块v3 by 司徒正美
//=========================================
$.define("lang", Array.isArray ? "" : "lang_fix",function(){
    // $.log("已加载语言扩展模块");
    var global = this, rascii = /[^\x00-\xff]/g,
    rformat = /\\?\#{([^{}]+)\}/gm,
    rnoclose = /^(area|base|basefont|bgsound|br|col|frame|hr|img|input|isindex|link|meta|param|embed|wbr)$/i,
    // JSON RegExp
    rvalidchars = /^[\],:{}\s]*$/,
    rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
    rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
    rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
    str_eval = global.execScript ? "execScript" : "eval",
    str_body = (global.open + '').replace(/open/g, '');
    $.mix({
        //判定是否是一个朴素的javascript对象(Object或JSON),不是DOM对象,不是BOM对象,不是自定义类的实例。
        isPlainObject: function (obj){
            if(!$.type(obj,"Object") || $.isNative(obj, "reload") ){
                return false;
            }
            try{//不存在hasOwnProperty方法的对象肯定是IE的BOM对象或DOM对象
                for(var key in obj)//只有一个方法是来自其原型立即返回flase
                    if(!({}).hasOwnProperty.call(obj, key)){//不能用obj.hasOwnProperty自己查自己
                        return false
                    }
            }catch(e){
                return false;
            }
            return true;
        },
        //判定method是否为obj的原生方法,如$.isNative(global,"JSON")
        isNative: function(obj, method) {
            var m = obj ? obj[method] : false, r = new RegExp(method, 'g');
            return !!(m && typeof m != 'string' && str_body === (m + '').replace(r, ''));
        },
        /**
         * 是否为空对象
         * @param {Object} obj
         * @return {Boolean}
         */
        isEmptyObject: function(obj ) {
            for ( var i in obj ){
                return false;
            }
            return true;
        },
        //限定为Array, Arguments, NodeList与拥有非负整数的length属性的Object对象,视情况添加字符串
        isArrayLike:  function (obj, str) {//是否包含字符串
            var type = $.type(obj);
            if(type === "Array" || type === "NodeList" || type === "Arguments" || str && type === "String"){
                return true;
            }
            if( type === "Object" ){
                var i = obj.length;
                return i >= 0 &&  parseInt( i ) === i;//非负整数
            }
            return false;
        },
        makeArray: function(obj){
            if (obj == null) {
                return [];
            }
            if($.isArrayLike(obj)){
                return $.slice( obj )
            }
            return [ obj ]
        },
        //将字符串中的占位符替换为对应的键值
        //http://www.cnblogs.com/rubylouvre/archive/2011/05/02/1972176.html
        format: function(str, object){
            var array = $.slice(arguments,1);
            return str.replace(rformat, function(match, name){
                if (match.charAt(0) == '\\')
                    return match.slice(1);
                var index = Number(name)
                if(index >=0 )
                    return array[index];
                if(object && object[name] !== void 0)
                    return  object[name];
                return  '' ;
            });
        },
        /**
         * 用于拼接多行HTML片断,免去写<与>与结束标签之苦
         * @param {String} tag 可带属性的开始标签
         * @param {String} innerHTML 可选
         * @param {Boolean} xml 可选 默认false,使用HTML模式,需要处理空标签
         * @example var html = T("P title=aaa",T("span","111111")("strong","22222"))("div",T("div",T("span","两层")))("H1",T("span","33333"))('',"这是纯文本");
         * console.log(html+"");
         * @return {Function}
         */
        tag: function (start, content, xml){
            xml = !!xml
            var chain = function(start, content, xml){
                var html = arguments.callee.html;
                start && html.push("<",start,">");
                content = ''+(content||'');
                content && html.push(content);
                var end = start.split(' ')[0];//取得结束标签
                if(end && (xml || !rnoclose.test(end))){
                    html.push("</",end,">");
                }
                return chain;
            }
            chain.html = [];
            chain.toString = function(){
                return this.html.join("");
            }
            return chain(start,content,xml);
        },
        // Generate an integer Array containing an arithmetic progression. A port of
        // the native Python `range()` function. See
        // [the Python documentation](http://docs.python.org/library/functions.html#range).
        range: function(start, stop, step) {
            step || (step = 1);
            if (arguments.length < 2) {
                stop = start || 0;
                start = 0;
            }
            var index = -1,
            length = Math.max(Math.ceil((stop - start) / step), 0),
            result = Array(length);
            while (++index < length) {
                result[index] = start;
                start += step;
            }
            return result;
        },
        // 为字符串两端添上双引号,并对内部需要转义的地方进行转义
        quote: global.JSON && JSON.stringify || String.quote ||  (function(){
            var meta = {
                '\t':'t',
                '\n':'n',
                '\v':'v',
                '\f':'f',
                '\r':'r',
                '\'':'\'',
                '\"':'\"',
                '\\':'\\'
            },
            reg = /[\x00-\x1F\'\"\\\u007F-\uFFFF]/g,
            regFn = function(c){
                if (c in meta) {
                    return '\\' + meta[c];
                }
                var ord = c.charCodeAt(0);
                return ord < 0x20   ? '\\x0' + ord.toString(16)
                :  ord < 0x7F   ? '\\'   + c
                :  ord < 0x100  ? '\\x'  + ord.toString(16)
                :  ord < 0x1000 ? '\\u0' + ord.toString(16)
                : '\\u'  + ord.toString(16)
            };
            return function (str) {
                return    '"' + str.replace(reg, regFn)+ '"';
            }
        })(),
        dump: function(obj, indent) {
            indent = indent || "";
            if (obj == null)//处理null,undefined
                return indent + "obj";
            if (obj.nodeType === 9)
                return indent + "[object Document]";
            if (obj.nodeType)
                return indent + "[object " + (obj.tagName || "Node") +"]";
            var arr = [], type = $.type(obj),self = $.dump ,next = indent +  "\t";
            switch (type) {
                case "Boolean":
                case "Number":
                case "NaN":
                case "RegExp":
                    return indent + obj;
                case "String":
                    return indent + $.quote(obj);
                case "Function":
                    return (indent + obj).replace(/\n/g, "\n" + indent);
                case "Date":
                    return indent + '(new Date(' + obj.valueOf() + '))';
                case "Window" :
                    return indent + "[object "+type +"]";
                default:
                    if($.isArrayLike(obj)){
                        for (var i = 0, n = obj.length; i < n; ++i)
                            arr.push(self(obj[i], next).replace(/^\s* /g, next));
                        return indent + "[\n" + arr.join(",\n") + "\n" + indent + "]";
                    }
                    if($.isPlainObject(obj)){
                        for ( i in obj) {
                            arr.push(next + self(i) + ": " + self(obj[i], next).replace(/^\s+/g, ""));
                        }
                        return indent + "{\n" + arr.join(",\n") + "\n" + indent + "}";
                    }
                    return indent + "[object "+type +"]";
            }
        },
        //http://www.schillmania.com/content/projects/javascript-animation-1/
        //http://www.cnblogs.com/rubylouvre/archive/2010/04/09/1708419.html
        parseJS: function( code ) {
            //IE中,global.eval()和eval()一样只在当前作用域生效。
            //Firefox,Safari,Opera中,直接调用eval()为当前作用域,global.eval()调用为全局作用域。
            if ( code && /\S/.test(code) ) {
                try{
                    global[str_eval](code);
                }catch(e){ }
            }
        },
        parseJSON: function( data ) {
            if ( typeof data !== "string" || !data ) {
                return null;
            }
            data = data.trim();
            if ( global.JSON && global.JSON.parse ) {
                //使用原生的JSON.parse转换字符串为对象
                return global.JSON.parse( data );
            }
            if ( rvalidchars.test( data.replace( rvalidescape, "@" )
                .replace( rvalidtokens, "]" )
                .replace( rvalidbraces, "")) ) {
                //使用new Function生成一个JSON对象
                return (new Function( "return " + data ))();
            }
            throw "Invalid JSON: " + data ;
        },

        // Cross-browser xml parsing
        parseXML: function ( data,xml,tmp ) {
            try {
                if ( global.DOMParser ) { // Standard
                    tmp = new DOMParser();
                    xml = tmp.parseFromString(data , "text/xml" );
                } else { // IE
                    xml = new ActiveXObject("Microsoft.XMLDOM" );//"Microsoft.XMLDOM"
                    xml.async = "false";
                    xml.loadXML( data );
                }
            } catch( e ) {
                xml = undefined;
            }
            if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
                throw "Invalid XML: " + data ;
            }
            return xml;
        },
        //http://oldenburgs.org/playground/autocomplete/
        //http://benalman.com/projects/jquery-throttle-debounce-plugin/
        //http://www.cnblogs.com/ambar/archive/2011/10/08/throttle-and-debounce.html
        throttle: function( delay, no_trailing, callback, debounce_mode ) {
            var timeout_id, last_exec = 0;//ms 时间内只执行 fn 一次, 即使这段时间内 fn 被调用多次
            if ( typeof no_trailing !== 'boolean' ) {
                debounce_mode = callback;
                callback = no_trailing;
                no_trailing = undefined;
            }
            function wrapper() {
                var that = this,
                elapsed = +new Date() - last_exec,
                args = arguments;
                function exec() {
                    last_exec = +new Date();
                    callback.apply( that, args );
                };
                function clear() {
                    timeout_id = undefined;
                };
                if ( debounce_mode && !timeout_id ) {
                    exec();
                }
                timeout_id && clearTimeout( timeout_id );
                if ( debounce_mode === undefined && elapsed > delay ) {
                    exec();
                } else if ( no_trailing !== true ) {
                    timeout_id = setTimeout( debounce_mode ? clear : exec, debounce_mode === undefined ? delay - elapsed : delay );
                }
            };
            wrapper.uniqueNumber = $.getUid(callback)
            return wrapper;
        },
        debounce : function( delay, at_begin, callback ) {
            return callback === undefined
            ? $.throttle( delay, at_begin, false )
            : $.throttle( delay, callback, at_begin !== false );
        }

    }, false);
   
    "Array,Function".replace($.rword, function( method ){
        $[ "is"+method ] = function(obj){
            return obj && ({}).toString.call(obj) === "[object "+method+"]";
        }
    });
    "each,map".replace($.rword, function( method ){
        $[ method ] = function(obj, fn, scope){
            return $[ $.isArrayLike(obj,true) ? "Array" : "Object" ][ method ](obj, fn, scope);
        }
    });
    if(Array.isArray){
        $.isArray = Array.isArray;
    }
    //这只是一个入口
    $.lang = function(obj, type){
        return adjust(new Chain, obj, type)
    }
    //调整Chain实例的重要属性
    function adjust(chain, obj, type){
        type = type || $.type(obj);
        if( type != "Array" && $.isArrayLike(type) ){
            obj = $.slice(obj);
            type = "Array";
        }
        chain.target = obj;
        chain.type = type;
        return chain
    }
    //语言链对象
    var Chain = function(){ }
    Chain.prototype = {
        constructor: Chain,
        toString: function(){
            return this.target + "";
        },
        value: function(){
            return this.target;
        }
    };

    var retouch = function(method){//函数变换,静态转原型
        return function(){
            [].unshift.call(arguments,this)
            return method.apply(null,arguments)
        }
    }
    var proto = Chain.prototype;
    //构建语言链对象的四个重要工具:$.String, $.Array, $.Number, $.Object
    "String,Array,Number,Object".replace($.rword, function(Type){
        $[ Type ] = function(ext){
            var isNative = typeof ext == "string",
            methods = isNative ? ext.match($.rword) : Object.keys(ext);
            methods.forEach(function(name){
                $[ Type ][name] = isNative ? function(obj){
                    return obj[name].apply(obj,$.slice(arguments,1) );
                } :  ext[name];
                proto[name] = function(){
                    var target = this.target;
                    if( target == null){
                        return this;
                    }else{
                        if( !(target[name] || $[ this.type ][name]) ){
                            throw "$."+ this.type + "."+name+" does not exist!"
                        }
                        var method = isNative ? target[name] : retouch( $[ this.type ][name] ),
                        next = this.target = method.apply( target, arguments ),
                        type = $.type( next );
                        if( type === this.type){
                            return this;
                        }else{
                            return adjust(this, next, type)
                        }
                    }
                }
            });
        }
    });
    
    $.String({
        //判断一个字符串是否包含另一个字符
        contains: function(target, str, separator){
            return (separator) ? !!~(separator + target + separator).indexOf(separator + str + separator) : !!~target.indexOf(str);
        },
        //判定是否以给定字符串开头
        startsWith: function(target, str, ignorecase) {
            var start_str = target.substr(0, str.length);
            return ignorecase ? start_str.toLowerCase() === str.toLowerCase() :
            start_str === str;
        },
        //判定是否以给定字符串结尾
        endsWith: function(target, str, ignorecase) {
            var end_str = target.substring(target.length - str.length);
            return ignorecase ? end_str.toLowerCase() === str.toLowerCase() :
            end_str === str;
        },
        //得到字节长度
        byteLen: function(target){
            return target.replace(rascii,"--").length;
        },

        //length,新字符串长度,truncation,新字符串的结尾的字段,返回新字符串
        truncate: function(target, length, truncation) {
            length = length || 30;
            truncation = truncation === void(0) ? '...' : truncation;
            return target.length > length ?
            target.slice(0, length - truncation.length) + truncation : String(target);
        },
        //转换为驼峰风格
        camelize: function(target){
            if (target.indexOf('-') < 0 && target.indexOf('_') < 0) {
                return target;//提前判断,提高getStyle等的效率
            }
            return target.replace(/[-_][^-_]/g, function (match) {
                return match.charAt(1).toUpperCase();
            });
        },
        //转换为连字符风格
        underscored: function(target) {
            return target.replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/\-/g, '_').toLowerCase();
        },
        //首字母大写
        capitalize: function(target){
            return target.charAt(0).toUpperCase() + target.substring(1).toLowerCase();
        },
        //去掉字符串中的html标签,但这方法有缺陷,如里面有script标签,会把这些不该显示出来的脚本也显示出来了
        stripTags: function (target) {
            return String(target ||"").replace(/<[^>]+>/g, '');
        },
        //移除字符串中所有的 HTML script 块。弥补stripTags方法对script标签的缺陷
        stripScripts: function(target){
            return String(target ||"").replace(/<script[^>]*>([\S\s]*?)<\/script>/img,'')
        },
        //将字符串中的html代码转换为可以直接显示的格式,
        escapeHTML:  function (target) {
            return target.replace(/&/g,'&')
            .replace(/</g,'<')
            .replace(/>/g,'>')
            .replace(/"/g, """)
            .replace(/'/g, "'");
        },
        //还原为可被文档解析的HTML标签
        unescapeHTML: function (target) {
            return  target.replace(/"/g,'"')
            .replace(/</g,'<')
            .replace(/>/g,'>')
            .replace(/&/g, "&");
            //处理转义的中文和实体字符
            return str.replace(/&#([\d]+);/g, function(_0, _1){
                return String.fromCharCode(parseInt(_1, 10));
            });
        },
        /**
 为目标字符串添加wbr软换行
1.支持html标签、属性以及字符实体。<br>
2.任意字符中间都会插入wbr标签,对于过长的文本,会造成dom节点元素增多,占用浏览器资源。
3.在opera下,浏览器默认css不会为wbr加上样式,导致没有换行效果,可以在css中加上 wbr:after { content: "\00200B" } 解决此问题*/
        wbr: function (target) {
            return String(target)
            .replace(/(?:<[^>]+>)|(?:&#?[0-9a-z]{2,6};)|(.{1})/gi, '$&<wbr>')
            .replace(/><wbr>/g, '>');
        },
        //http://stevenlevithan.com/regex/xregexp/
        //将字符串安全格式化为正则表达式的源码
        escapeRegExp: function( target ){
            return target.replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1');
        },
        //http://www.cnblogs.com/rubylouvre/archive/2010/02/09/1666165.html
        //在左边补上一些字符,默认为0
        padLeft: function( target, digits, filling, radix , right){
            var num = target.toString(radix || 10);
            filling = filling || "0";
            while(num.length < digits){
                if(!right){
                    num = filling + num;
                }else{
                    num += filling;
                }
            }
            return num;
        },
        //在右边补上一些字符,默认为0
        padRight: function(target, digits, filling, radix){
            return $.String.padLeft(target, digits, filling, radix, true)
        }
    });
    $.String("charAt,charCodeAt,concat,indexOf,lastIndexOf,localeCompare,match,"+
        "replace,search,slice,split,substring,toLowerCase,toLocaleLowerCase,toUpperCase,trim,toJSON")
    $.Array({
        //深拷贝当前数组
        clone: function( target ){
            var i = target.length, result = [];
            while (i--) result[i] = cloneOf(target[i]);
            return result;
        },
        each: function( target, fn, scope  ){
            for(var i = 0, n = target.length; i < n; i++){
                if (fn.call(scope || target[i], target[i], i, target) === false)
                    break;
            }
            return target;
        },
        //取得第一个元素或对它进行操作
        first: function( target, fn, scope ){
            if($.type(fn,"Function")){
                for(var i=0, n = target.length; i < n; i++){
                    if(fn.call( scope,target[i], i, target )){
                        return target[i];
                    }
                }
                return null;
            }else{
                return target[0];
            }
        },
        //取得最后一个元素或对它进行操作
        last: function( target, fn, scope ) {
            if($.type(fn,"Function")){
                for (var i=target.length-1; i > -1; i--) {
                    if (fn.call(scope, target[i], i, target)) {
                        return target[i];
                    }
                }
                return null;
            }else{
                return target[target.length-1];
            }
        },
        //判断数组是否包含此元素
        contains: function ( target, item ) {
            return !!~target.indexOf(item) ;
        },
        //http://msdn.microsoft.com/zh-cn/library/bb383786.aspx
        //移除 Array 对象中某个元素的第一个匹配项。
        remove: function ( target, item ) {
            var index = target.indexOf(item);
            if (~index ) return $.Array.removeAt(target, index);
            return null;
        },
        //移除 Array 对象中指定位置的元素。
        removeAt: function ( target, index ) {
            return target.splice(index, 1);
        },
        //对数组进行洗牌,但不影响原对象
        // Jonas Raoni Soares Silva http://jsfromhell.com/array/shuffle [v1.0]
        shuffle: function ( target ) {
            var shuff = target.concat(), j, x, i = shuff.length;
            for (; i > 0; j = parseInt(Math.random() * i), x = shuff[--i], shuff[i] = shuff[j], shuff[j] = x) {};
            return shuff;
        },
        //从数组中随机抽选一个元素出来
        random: function ( target ) {
            return $.Array.shuffle( target )[0];
        },
        //取得数字数组中值最小的元素
        min: function( target ) {
            return Math.min.apply(0, target);
        },
        //取得数字数组中值最大的元素
        max: function( target ) {
            return Math.max.apply(0, target);
        },
        //取得对象数组的每个元素的特定属性
        pluck: function( target, name ){
            var result = [], prop;
            target.forEach(function(item){
                prop = item[name];
                if(prop != null)
                    result.push(prop);
            });
            return result;
        },
        //根据对象的某个属性进行排序
        sortBy: function( target, fn, scope ) {
            var array =  target.map(function(item, index) {
                return {
                    el: item,
                    re: fn.call(scope, item, index)
                };
            }).sort(function(left, right) {
                var a = left.re, b = right.re;
                return a < b ? -1 : a > b ? 1 : 0;
            });
            return $.Array.pluck(array,'el');
        },
        // 以数组形式返回原数组中不为null与undefined的元素
        compact: function ( target ) {
            return target.filter(function (el) {
                return el != null;
            });
        },
        //取差集(补集)
        diff: function( target, array ) {
            var result = target.slice();
            for ( var i = 0; i < result.length; i++ ) {
                for ( var j = 0; j < array.length; j++ ) {
                    if ( result[i] === array[j] ) {
                        result.splice(i, 1);
                        i--;
                        break;
                    }
                }
            }
            return result;
        },
        merge: function( target, array ){
            var i = target.length, j = 0;
            for ( var n = array.length; j < n; j++ ) {
                target[ i++ ] = array[ j ];
            }
            target.length = i;
            return target;
        },
        //取并集
        union: function( target, array ){
            $.Array.merge(target, array)
            return $.Array.unique( target );
        },
        //取交集
        intersect: function( target, array ){
            return target.filter(function(n) {
                return ~array.indexOf(n);
            });
        },
        // 返回没有重复值的新数组
        unique: function ( target ) {
            var result = [];
                o:for(var i = 0, n = target.length; i < n; i++) {
                    for(var x = i + 1 ; x < n; x++) {
                        if(target[x] === target[i])
                            continue o;
                    }
                    result.push(target[i]);
                }
            return result;
        },
        //对数组进行平坦化处理,返回一个一维数组
        flatten: function(target) {
            var result = [],self = $.Array.flatten;
            target.forEach(function(item) {
                if ($.isArray(item)) {
                    result = result.concat(self(item));
                } else {
                    result.push(item);
                }
            });
            return result;
        }
    });
    $.Array("concat,join,pop,push,shift,slice,sort,reverse,splice,unshift"+
        "indexOf,lastIndexOf,every,some,forEach,map,filter,reduce,reduceRight")
    var NumberExt = {
        times: function(target, fn, bind) {
            for (var i=0; i < target; i++)
                fn.call(bind, i);
            return target;
        },
        //确保数值在[n1,n2]闭区间之内,如果超出限界,则置换为离它最近的最大值或最小值
        constrain: function(target, n1, n2){
            var a = [n1, n2].sort();
            if(target < a[0]) target = a[0];
            if(target > a[1]) target = a[1];
            return target;
        },
        upto: function(target, number, fn, scope) {
            for (var i=target+0; i <= number; i++)
                fn.call(scope, i);
            return target;
        },
        downto: function(target, number, fn, scope) {
            for (var i=target+0; i >= number; i--)
                fn.call(scope, i);
            return target;
        },
        //求出距离原数最近的那个数
        nearer: function(target, n1, n2){
            var diff1 = Math.abs(target - n1),
            diff2 = Math.abs(target - n2);
            return diff1 < diff2 ? n1 : n2
        },
        round: function(target, base) {
            if (base) {
                base = Math.pow(10, base);
                return Math.round(target * base) / base;
            } else {
                return Math.round(target);
            }
        }
    }
    "padLeft,padRight".replace($.rword, function(name){
        NumberExt[name] = $.String[name];
    });
    "abs,acos,asin,atan,atan2,ceil,cos,exp,floor,log,pow,sin,sqrt,tan".replace($.rword,function(name){
        NumberExt[name] = Math[name];
    });
    $.Number(NumberExt);
    $.Number("toFixed,toExponential,toPrecision,toJSON")
    function cloneOf(item){
        var name = $.type(item);
        switch(name){
            case "Array":
            case "Object":
                return $[name].clone(item);
            default:
                return item;
        }       
    }
    //使用深拷贝方法将多个对象或数组合并成一个
    function mergeOne(source, key, current){
        if( $.isPlainObject(source[key]) ){//只处理纯JS对象,不处理window与节点
            $.Object.merge(source[key], current);
        }else {
            source[key] = cloneOf(current)
        }
        return source;
    };

    $.Object({
        //根据传入数组取当前对象相关的键值对组成一个新对象返回
        subset: function(target, props){
            var result = {};
            props.forEach(function(prop){
                result[prop] = target[prop];
            });
            return result;
        },
        //遍历对象的键值对
        each: function(target, fn, scope){
            var keys = Object.keys(target);
            for(var i = 0, n = keys.length; i < n; i++){
                var key = keys[i], value = target[key];
                if (fn.call(scope || value, value, key, target) === false)
                    break;
            }
            return target;
        },
        map: function(target, fn, scope){
            return Object.keys(target).map(function(name){
                return fn.call(scope, target[name], name, target);
            }, target);
        },
        //进行深拷贝,返回一个新对象,如果是拷贝请使用$.mix
        clone: function(target){
            var clone = {};
            for (var key in target) {
                clone[key] = cloneOf(target[key]);
            }
            return clone;
        },
        merge: function(target, k, v){
            var obj, key;
            //为目标对象添加一个键值对
            if (typeof k === "string")
                return mergeOne(target, k, v);
            //合并多个对象
            for (var i = 1, n = arguments.length; i < n; i++){
                obj = arguments[i];
                for ( key in obj){
                    if(obj[key] !== void 0){
                        mergeOne(target, key, obj[key]);
                    }
                }
            }
            return target;
        },
        //去掉与传入参数相同的元素
        without: function(target, array) {
            var result = {}, key;
            for (key in target) {//相当于构建一个新对象,把不位于传入数组中的元素赋给它
                if (!~array.indexOf(key) ) {
                    result[key] = target[key];
                }
            }
            return result;
        }
    });
    $.Object("hasOwnerProperty,isPrototypeOf,propertyIsEnumerable");
    return $.lang;
});

posted on 2012-06-05 13:57  司徒正美  阅读(1112)  评论(0编辑  收藏  举报