JsUtil.js function JSUtil() { }//var value = [];//value.constructor.name == 'Array'; value instanceof Array// Array.isArray(value) == true; // Chrome 5+, Firefox 4.0+, IE 9+, Opera 10.5+ and Safari 5+// Object.prototype.toString.call(value)
function JSUtil() { }
//var value = [];
//value.constructor.name == 'Array'; value instanceof Array
// Array.isArray(value) == true; // Chrome 5+, Firefox 4.0+, IE 9+, Opera 10.5+ and Safari 5+
// Object.prototype.toString.call(value) === '[object Array]'
//
//function isArray(obj){ return !!obj && obj.constructor === Array; }
//Utils.isArray = ('isArray' in Array) ? Array.isArray :
//function (value) {
// return Object.prototype.toString.call(value) === '[object Array]';
//}
/** Determines whether the passed value is an `Array`. */
JSUtil.isArray = ('isArray' in Array) ? Array.isArray : function (value) {
return Object.prototype.toString.call(value) === '[object Array]';
};
/**
* Gets the value at `path` of `object`. If the resolved value is
* `undefined`, the `defaultValue` is returned in its place.
*
* @static
* @param {Object} object The object to query.
* @param {Array|string} path The path of the property to get.
* @param {*} [defaultValue] The value returned for `undefined` resolved values.
* @returns {*} Returns the resolved value.
* @example
* var object = { 'a': [{ 'b': { 'c': 3 } }] };
* JSUtil.derefOpt(object, 'a[0].b.c'); // => 3
* JSUtil.derefOpt(object, ['a', '0', 'b', 'c']); // => 3
* _.derefOpt(object, 'a.b.c', 'default'); // => 'default'
*/
JSUtil.derefOpt = function (object, path, defaultValue) {
var result = object == null ? undefined : derefGet(object, path);
return result === undefined ? defaultValue : result;
};
/**
* The base implementation of `_.get` without support for default values.
*
* @private
* @param {Object} object The object to query.
* @param {Array|string} path The path of the property to get.
* @returns {*} Returns the resolved value.
*/
JSUtil.derefGet = function (object, path) {
if (!JSUtil.isArray(path)) path = path.split('.');
//inspect the property path array against {object}
var index = 0, length = path.length;
while (object != null && index < length) {
object = object[path[index++]];
}
return (index && index == length) ? object : undefined;
};
// https://stackoverflow.com/questions/6393943/convert-javascript-string-in-dot-notation-into-an-object-reference#30360979
// https://jsperf.com/dereference-object-property-path-from-string/4
// TODO optmize: if you need to dereference the same paths a long time apart, the jsperf.com link above shows an example of
// how to save and look up the function later. The act of calling the Function constructor is fairly slow, so high-perf code
// should memoize the results to avoid repeating it if possible.
JSUtil.memoizedLookupFunction = function (obj, path, derefFuncs) {
if (!derefFuncs) {
derefFuncs = {};
}
if (!derefFuncs[path]) { /*jshint evil:true */
derefFuncs[path] = Function("obj", "return obj." + path + ";");
}
return derefFuncs[path](obj);
};
/**
* Buid a string representing a JavaScript expression for a function, which can
* be passed as the argument of `eval`
* @param {Function} func a `Function` object
* @param {...*} args Argument `Ojects` to be used by the function as formal argument, allowed to be repeated
* @return A string representing a JavaScript expression calling the function
* @example
* var arr = ['incident', 'task'];
* function method(obj1, obj2){console.log('%o, %o, all: %o', obj1, obj2, arguments);}
* var str = buildEvalStringForFunction(method, arr);
* eval(str); // test it
*/
JSUtil.buildEvalStringForFunction = function (func, args) {
var argStrings = [];
for (var idx = 1, cnt = arguments.length; idx < cnt; ++idx) {
argStrings.push(JSON.stringify(arguments[idx]));
}
return '(' + func.toString() + ')(' + argStrings.join(', ') + ');';
};
/// Commons Logging which is a simple logging facade for the underlying logging interface.
/**
* @param {string} tag
* @param {string} msg
* @param {...*} [args]
* @example logdebug('tag', 'msg: %s, %o', [true, 'hasarg'].join(), {arg: 2});
*/
function logdebug(tag, msg){
//var args = [console.log]; args.push.apply(args, arguments);
Array.prototype.unshift.call(arguments, console.log);
loglv.apply(null, arguments);
}
/**
* Outputs a message using the specified function.
* @private
* @param {function} gslv such as `console.log`
* @param {string} tag prefix of the first parameter of `gslv`
* @param {string} msg it will be passed as the first parameter of `gslv`
* @param {...*} [args]
*/
function loglv(gslv, tag, msg){
var fmt = tag + '|' + msg;
// debugger; // jshint ignore:line
gslv.apply(Array.prototype.splice.call(arguments, 0, 3, fmt)[0], arguments);
}
/**
* Outputs a debbug message.
* @param {string} tag message prefix (Don't contain any substitution string, e.g. for log4j style: {0}, {1},...; c printf style: %s, %o, ...)
* @param {string} msg A JavaScript string containing zero or more substitution strings.
* @param {...*} [args] JavaScript objects with which to replace substitution strings within `msg`. This gives you additional control over the format of the output.
* @example logDebug('tag', 'msg: %s, %o', [true, 'hasarg'].join(), {arg: 2});
*/
function logDebug(tag, msg){ loglva(console.log, arguments); }
/**
* Outputs a message using the specified function.
* @private
* @param {function} gslv such as `console.log`
* @param {object[]} args [tag, msg]
* @param {string} args[0] tag message prefix of the first parameter of `gslv`
* @param {string} args[1] msg, it will be passed as the first parameter of `gslv`
*/
function loglva(gslv, args){
var fmt = args[0] + '|' + args[1];
Array.prototype.splice.call(args, 0, 2, fmt);
gslv.apply(gslv, args);
}
