cocosjs源码阅读1-工具函数

/**

* Iterate over an object or an array, executing a function for each matched element.

* @param {object|array} obj

* @param {function} iterator

* @param {object} [context]

*/

cc.each = function (obj, iterator, context) {

    if (!obj)

        return;

    if (obj instanceof Array) {

        for (var i = 0, li = obj.length; i < li; i++) {

            if (iterator.call(context, obj[i], i) === false)

                return;

        }

    } else {

        for (var key in obj) {

            if (iterator.call(context, obj[key], key) === false)

                return;

        }

    }

};

/**

* Copy all of the properties in source objects to target object and return the target object.

* @param {object} target

* @param {object} *sources

* @returns {object}

*/

cc.extend = function (target) {

    var sources = arguments.length >= 2 ? Array.prototype.slice.call(arguments, 1) : [];

    cc.each(sources, function (src) {

        for (var key in src) {

            if (src.hasOwnProperty(key)) {

                target[key] = src[key];

            }

        }

    });

    return target;

};

/**

* Another way to subclass: Using Google Closure.

* The following code was copied + pasted from goog.base / goog.inherits

* @function

* @param {Function} childCtor

* @param {Function} parentCtor

*/

cc.inherits = function (childCtor, parentCtor) {

    function tempCtor() {}

    tempCtor.prototype = parentCtor.prototype;

    childCtor.superClass_ = parentCtor.prototype;

    childCtor.prototype = new tempCtor();

    childCtor.prototype.constructor = childCtor;

    // Copy "static" method, but doesn't generate subclasses.

    // for( var i in parentCtor ) {

    // childCtor[ i ] = parentCtor[ i ];

    // }

};

/**

* Check the obj whether is function or not

* @param {*} obj

* @returns {boolean}

*/

cc.isFunction = function (obj) {

    return typeof obj === 'function';

};

/**

* Check the obj whether is number or not

* @param {*} obj

* @returns {boolean}

*/

cc.isNumber = function (obj) {

    return typeof obj === 'number' || Object.prototype.toString.call(obj) === '[object Number]';

};

/**

* Check the obj whether is string or not

* @param {*} obj

* @returns {boolean}

*/

cc.isString = function (obj) {

    return typeof obj === 'string' || Object.prototype.toString.call(obj) === '[object String]';

};

/**

* Check the obj whether is array or not

* @param {*} obj

* @returns {boolean}

*/

cc.isArray = function (obj) {

    return Array.isArray(obj) ||

        (typeof obj === 'object' && Object.prototype.toString.call(obj) === '[object Array]');

};

/**

* Check the obj whether is undefined or not

* @param {*} obj

* @returns {boolean}

*/

cc.isUndefined = function (obj) {

    return typeof obj === 'undefined';

};

/**

* Check the obj whether is object or not

* @param {*} obj

* @returns {boolean}

*/

cc.isObject = function (obj) {

    return typeof obj === "object" && Object.prototype.toString.call(obj) === '[object Object]';

};

/**

* Check the url whether cross origin

* @param {String} url

* @returns {boolean}

*/

cc.isCrossOrigin = function (url) {

    if (!url) {

        cc.log("invalid URL");

        return false;

    }

    var startIndex = url.indexOf("://");

    if (startIndex === -1)

        return false;

    var endIndex = url.indexOf("/", startIndex + 3);

    var urlOrigin = (endIndex === -1) ? url : url.substring(0, endIndex);

    return urlOrigin !== location.origin;

};

//+++++++++++++++++++++++++something about async begin+++++++++++++++++++++++++++++++

/**

* Async Pool class, a helper of cc.async

* @param {Object|Array} srcObj

* @param {Number} limit the limit of parallel number

* @param {function} iterator

* @param {function} onEnd

* @param {object} target

* @constructor

*/

cc.AsyncPool = function (srcObj, limit, iterator, onEnd, target) {

    var self = this;

    self._finished = false;

    self._srcObj = srcObj;

    self._limit = limit;

    self._pool = [];

    self._iterator = iterator;

    self._iteratorTarget = target;

    self._onEnd = onEnd;

    self._onEndTarget = target;

    self._results = srcObj instanceof Array ? [] : {};

    self._errors = srcObj instanceof Array ? [] : {};

    cc.each(srcObj, function (value, index) {

        self._pool.push({index: index, value: value});

    });

    self.size = self._pool.length;

    self.finishedSize = 0;

    self._workingSize = 0;

    self._limit = self._limit || self.size;

    self.onIterator = function (iterator, target) {

        self._iterator = iterator;

        self._iteratorTarget = target;

    };

    self.onEnd = function (endCb, endCbTarget) {

        self._onEnd = endCb;

        self._onEndTarget = endCbTarget;

    };

    self._handleItem = function () {

        var self = this;

        if (self._pool.length === 0 || self._workingSize >= self._limit)

            return;                                                        //return directly if the array's length = 0 or the working size great equal limit number

        var item = self._pool.shift();

        var value = item.value, index = item.index;

        self._workingSize++;

        self._iterator.call(self._iteratorTarget, value, index,

            function (err, result) {

                if (self._finished) {

                    return;

                }

                if (err) {

                    self._errors[this.index] = err;

                }

                else {

                    self._results[this.index] = result;

                }

                self.finishedSize++;

                self._workingSize--;

                if (self.finishedSize === self.size) {

                    var errors = self._errors.length === 0 ? null : self._errors;

                    self.onEnd(errors, self._results);

                    return;

                }

                self._handleItem();

            }.bind(item),

            self);

    };

    self.flow = function () {

        var self = this;

        if (self._pool.length === 0) {

            if (self._onEnd)

                self._onEnd.call(self._onEndTarget, null, []);

            return;

        }

        for (var i = 0; i < self._limit; i++)

            self._handleItem();

    };

    self.onEnd = function(errors, results) {

        self._finished = true;

        if (self._onEnd) {

            var selector = self._onEnd;

            var target = self._onEndTarget;

            self._onEnd = null;

            self._onEndTarget = null;

            selector.call(target, errors, results);

        }

    };

};

/**

* @class

*/

cc.async = /** @lends cc.async# */{

    /**

    * Do tasks series.

    * @param {Array|Object} tasks

    * @param {function} [cb] callback

    * @param {Object} [target]

    * @return {cc.AsyncPool}

    */

    series: function (tasks, cb, target) {

        var asyncPool = new cc.AsyncPool(tasks, 1, function (func, index, cb1) {

            func.call(target, cb1);

        }, cb, target);

        asyncPool.flow();

        return asyncPool;

    },

    /**

    * Do tasks parallel.

    * @param {Array|Object} tasks

    * @param {function} cb callback

    * @param {Object} [target]

    * @return {cc.AsyncPool}

    */

    parallel: function (tasks, cb, target) {

        var asyncPool = new cc.AsyncPool(tasks, 0, function (func, index, cb1) {

            func.call(target, cb1);

        }, cb, target);

        asyncPool.flow();

        return asyncPool;

    },

    /**

    * Do tasks waterfall.

    * @param {Array|Object} tasks

    * @param {function} cb callback

    * @param {Object} [target]

    * @return {cc.AsyncPool}

    */

    waterfall: function (tasks, cb, target) {

        var args = [];

        var lastResults = [null];//the array to store the last results

        var asyncPool = new cc.AsyncPool(tasks, 1,

            function (func, index, cb1) {

                args.push(function (err) {

                    args = Array.prototype.slice.call(arguments, 1);

                    if (tasks.length - 1 === index) lastResults = lastResults.concat(args);//while the last task

                    cb1.apply(null, arguments);

                });

                func.apply(target, args);

            }, function (err) {

                if (!cb)

                    return;

                if (err)

                    return cb.call(target, err);

                cb.apply(target, lastResults);

            });

        asyncPool.flow();

        return asyncPool;

    },

    /**

    * Do tasks by iterator.

    * @param {Array|Object} tasks

    * @param {function|Object} iterator

    * @param {function} [callback]

    * @param {Object} [target]

    * @return {cc.AsyncPool}

    */

    map: function (tasks, iterator, callback, target) {

        var locIterator = iterator;

        if (typeof(iterator) === "object") {

            callback = iterator.cb;

            target = iterator.iteratorTarget;

            locIterator = iterator.iterator;

        }

        var asyncPool = new cc.AsyncPool(tasks, 0, locIterator, callback, target);

        asyncPool.flow();

        return asyncPool;

    },

    /**

    * Do tasks by iterator limit.

    * @param {Array|Object} tasks

    * @param {Number} limit

    * @param {function} iterator

    * @param {function} cb callback

    * @param {Object} [target]

    */

    mapLimit: function (tasks, limit, iterator, cb, target) {

        var asyncPool = new cc.AsyncPool(tasks, limit, iterator, cb, target);

        asyncPool.flow();

        return asyncPool;

    }

};

//+++++++++++++++++++++++++something about async end+++++++++++++++++++++++++++++++++

//+++++++++++++++++++++++++something about path begin++++++++++++++++++++++++++++++++

/**

* @class

*/

cc.path = /** @lends cc.path# */{

    normalizeRE: /[^\.\/]+\/\.\.\//,

    /**

    * Join strings to be a path.

    * @example

    cc.path.join("a", "b.png");//-->"a/b.png"

    cc.path.join("a", "b", "c.png");//-->"a/b/c.png"

    cc.path.join("a", "b");//-->"a/b"

    cc.path.join("a", "b", "/");//-->"a/b/"

    cc.path.join("a", "b/", "/");//-->"a/b/"

    * @returns {string}

    */

    join: function () {

        var l = arguments.length;

        var result = "";

        for (var i = 0; i < l; i++) {

            result = (result + (result === "" ? "" : "/") + arguments[i]).replace(/(\/|\\\\)$/, "");

        }

        return result;

    },

    /**

    * Get the ext name of a path.

    * @example

    cc.path.extname("a/b.png");//-->".png"

    cc.path.extname("a/b.png?a=1&b=2");//-->".png"

    cc.path.extname("a/b");//-->null

    cc.path.extname("a/b?a=1&b=2");//-->null

    * @param {string} pathStr

    * @returns {*}

    */

    extname: function (pathStr) {

        var temp = /(\.[^\.\/\?\\]*)(\?.*)?$/.exec(pathStr);

        return temp ? temp[1] : null;

    },

    /**

    * Get the main name of a file name

    * @param {string} fileName

    * @returns {string}

    */

    mainFileName: function (fileName) {

        if (fileName) {

            var idx = fileName.lastIndexOf(".");

            if (idx !== -1)

                return fileName.substring(0, idx);

        }

        return fileName;

    },

    /**

    * Get the file name of a file path.

    * @example

    cc.path.basename("a/b.png");//-->"b.png"

    cc.path.basename("a/b.png?a=1&b=2");//-->"b.png"

    cc.path.basename("a/b.png", ".png");//-->"b"

    cc.path.basename("a/b.png?a=1&b=2", ".png");//-->"b"

    cc.path.basename("a/b.png", ".txt");//-->"b.png"

    * @param {string} pathStr

    * @param {string} [extname]

    * @returns {*}

    */

    basename: function (pathStr, extname) {

        var index = pathStr.indexOf("?");

        if (index > 0) pathStr = pathStr.substring(0, index);

        var reg = /(\/|\\\\)([^(\/|\\\\)]+)$/g;

        var result = reg.exec(pathStr.replace(/(\/|\\\\)$/, ""));

        if (!result) return null;

        var baseName = result[2];

        if (extname && pathStr.substring(pathStr.length - extname.length).toLowerCase() === extname.toLowerCase())

            return baseName.substring(0, baseName.length - extname.length);

        return baseName;

    },

    /**

    * Get dirname of a file path.

    * @example

    * unix

    cc.path.driname("a/b/c.png");//-->"a/b"

    cc.path.driname("a/b/c.png?a=1&b=2");//-->"a/b"

    cc.path.dirname("a/b/");//-->"a/b"

    cc.path.dirname("c.png");//-->""

    * windows

    cc.path.driname("a\\b\\c.png");//-->"a\b"

    cc.path.driname("a\\b\\c.png?a=1&b=2");//-->"a\b"

    * @param {string} pathStr

    * @returns {*}

    */

    dirname: function (pathStr) {

        return pathStr.replace(/((.*)(\/|\\|\\\\))?(.*?\..*$)?/, '$2');

    },

    /**

    * Change extname of a file path.

    * @example

    cc.path.changeExtname("a/b.png", ".plist");//-->"a/b.plist"

    cc.path.changeExtname("a/b.png?a=1&b=2", ".plist");//-->"a/b.plist?a=1&b=2"

    * @param {string} pathStr

    * @param {string} [extname]

    * @returns {string}

    */

    changeExtname: function (pathStr, extname) {

        extname = extname || "";

        var index = pathStr.indexOf("?");

        var tempStr = "";

        if (index > 0) {

            tempStr = pathStr.substring(index);

            pathStr = pathStr.substring(0, index);

        }

        index = pathStr.lastIndexOf(".");

        if (index < 0) return pathStr + extname + tempStr;

        return pathStr.substring(0, index) + extname + tempStr;

    },

    /**

    * Change file name of a file path.

    * @example

    cc.path.changeBasename("a/b/c.plist", "b.plist");//-->"a/b/b.plist"

    cc.path.changeBasename("a/b/c.plist?a=1&b=2", "b.plist");//-->"a/b/b.plist?a=1&b=2"

    cc.path.changeBasename("a/b/c.plist", ".png");//-->"a/b/c.png"

    cc.path.changeBasename("a/b/c.plist", "b");//-->"a/b/b"

    cc.path.changeBasename("a/b/c.plist", "b", true);//-->"a/b/b.plist"

    * @param {String} pathStr

    * @param {String} basename

    * @param {Boolean} [isSameExt]

    * @returns {string}

    */

    changeBasename: function (pathStr, basename, isSameExt) {

        if (basename.indexOf(".") === 0) return this.changeExtname(pathStr, basename);

        var index = pathStr.indexOf("?");

        var tempStr = "";

        var ext = isSameExt ? this.extname(pathStr) : "";

        if (index > 0) {

            tempStr = pathStr.substring(index);

            pathStr = pathStr.substring(0, index);

        }

        index = pathStr.lastIndexOf("/");

        index = index <= 0 ? 0 : index + 1;

        return pathStr.substring(0, index) + basename + ext + tempStr;

    },

    //todo make public after verification

    _normalize: function (url) {

        var oldUrl = url = String(url);

        //removing all ../

        do {

            oldUrl = url;

            url = url.replace(this.normalizeRE, "");

        } while (oldUrl.length !== url.length);

        return url;

    }

};

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容