自定义 'use strict' 类指令
custom 'use strict' like directives
我正在为我的项目寻找更好的 logging/debugging 方法。所以我想出了使用像 'use strict'.
这样的自定义指令的想法
能不能这样写
function xyz () {
'loglevel: info';
/// Some other code
logging.debug("foobar");
}
如果 xyz 有指令 loglevel >= info,logging.debug 将不会记录消息。
这可能吗?
不,如果没有一些真正的技巧将当前函数转换为字符串并检查指令,您就不能创建这样的指令。不值得花时间检查。但是,您可以使用函数式装饰器来执行相同的功能,这有点棘手,但一旦您做到了,它就会非常强大。
我应该提到 es7 将有更容易实现的装饰器。它们仍然以相同的方式创建。它们是一个函数,即 returns 一个函数代替了原来的函数。但是他们有糖例如
sorry I couldn't stop so went a bit far. but now it's a pretty complete example.
@logLevel('warn')
function xyz(){
// do some stuff
}
或
@logLevelInfo
function abc(){
// do some stuff
}
// if this is false the logging will not occur
var __debug__ = true;
var __debug_levels__ = ['error', 'warn'];
// decorator to create a log level function. this is a function
// that takes the log type, that returns a function that takes the
// function you want to decorate with the logging functionality
// that returns the decorated function that you call as xyz( ...arguments ).
function logLevel( type ) {
return function logger(fn) {
return function() {
// save time if __debug__ is false
if( __debug__ ){
// run the decorated function and get the result
// may as well wrap it in a try catch in case there are any errors
try {
var result = fn.apply(this, arguments);
} catch( e ){
console.error( e );
}
if( __debug_levels__.indexOf( type ) > -1 ){
// log the result to the console or whatever functionality you require
console[ type || 'log' ](result);
}
// return the result so you can do something with the result
return result;
}
return fn.apply(this, arguments);
}
}
}
// this will return the first function that takes the function to decorate
var logLevelInfo = logLevel('warn');
var logLevelDebug = logLevel('error');
// here we are using the decorators to wrap the original function
var xyz = logLevelInfo(function xyz( arg ) {
return arg + 'bar';
});
// same here but we are using the other decorator
var abc = logLevelDebug(function abc( arg ){
return arg + 'baz';
});
// these functions have been decorated to perform the logging
// functionality on the returned result
xyz('foo'); //=> 'foobar'
abc('foo'); //=> 'foobaz'
<script src="http://codepen.io/synthet1c/pen/WrQapG.js"></script>
function Log(level)
{
var levels = { 'debug': 10, 'info': 20};
function write(lvl)
{
var handle = function(msg)
{
if (levels[lvl] <= levels[level])
console.log(lvl + ': ' + msg);
};
return handle;
}
for (var i in levels)
{
this[i] = write(i);
}
}
var log1 = new Log('info');
log1.info('hello'); // will result with an output
log1.debug('hello'); // still has an output output
var log2 = new Log('debug');
log2.info('hello'); // no output here
我正在为我的项目寻找更好的 logging/debugging 方法。所以我想出了使用像 'use strict'.
这样的自定义指令的想法能不能这样写
function xyz () {
'loglevel: info';
/// Some other code
logging.debug("foobar");
}
如果 xyz 有指令 loglevel >= info,logging.debug 将不会记录消息。
这可能吗?
不,如果没有一些真正的技巧将当前函数转换为字符串并检查指令,您就不能创建这样的指令。不值得花时间检查。但是,您可以使用函数式装饰器来执行相同的功能,这有点棘手,但一旦您做到了,它就会非常强大。
我应该提到 es7 将有更容易实现的装饰器。它们仍然以相同的方式创建。它们是一个函数,即 returns 一个函数代替了原来的函数。但是他们有糖例如
sorry I couldn't stop so went a bit far. but now it's a pretty complete example.
@logLevel('warn')
function xyz(){
// do some stuff
}
或
@logLevelInfo
function abc(){
// do some stuff
}
// if this is false the logging will not occur
var __debug__ = true;
var __debug_levels__ = ['error', 'warn'];
// decorator to create a log level function. this is a function
// that takes the log type, that returns a function that takes the
// function you want to decorate with the logging functionality
// that returns the decorated function that you call as xyz( ...arguments ).
function logLevel( type ) {
return function logger(fn) {
return function() {
// save time if __debug__ is false
if( __debug__ ){
// run the decorated function and get the result
// may as well wrap it in a try catch in case there are any errors
try {
var result = fn.apply(this, arguments);
} catch( e ){
console.error( e );
}
if( __debug_levels__.indexOf( type ) > -1 ){
// log the result to the console or whatever functionality you require
console[ type || 'log' ](result);
}
// return the result so you can do something with the result
return result;
}
return fn.apply(this, arguments);
}
}
}
// this will return the first function that takes the function to decorate
var logLevelInfo = logLevel('warn');
var logLevelDebug = logLevel('error');
// here we are using the decorators to wrap the original function
var xyz = logLevelInfo(function xyz( arg ) {
return arg + 'bar';
});
// same here but we are using the other decorator
var abc = logLevelDebug(function abc( arg ){
return arg + 'baz';
});
// these functions have been decorated to perform the logging
// functionality on the returned result
xyz('foo'); //=> 'foobar'
abc('foo'); //=> 'foobaz'
<script src="http://codepen.io/synthet1c/pen/WrQapG.js"></script>
function Log(level)
{
var levels = { 'debug': 10, 'info': 20};
function write(lvl)
{
var handle = function(msg)
{
if (levels[lvl] <= levels[level])
console.log(lvl + ': ' + msg);
};
return handle;
}
for (var i in levels)
{
this[i] = write(i);
}
}
var log1 = new Log('info');
log1.info('hello'); // will result with an output
log1.debug('hello'); // still has an output output
var log2 = new Log('debug');
log2.info('hello'); // no output here