我想创建自己的console.log版本,使用咖喱'功能,包括显示或不显示日志的可能性。 (灵感来自SecretsOfTheJavascriptNinja)
所以我使用闭包实现了这个功能:
Function.prototype.conditionalCurry = function() {
var fn = this;
var args = Array.prototype.slice.call(arguments);
var show = args[0];
args = args.slice(1, args.length);
return function() {
if (show) {
return fn.apply(this, args.concat(
Array.prototype.slice.call(arguments)));
}
else return;
};
};
当我使用终端中的节点测试代码时,它可以工作:
var newLog = console.log.conditionalCurry(true, 'Always visible|' );
newLog('log visible'); // gives on the console: Always visible| log visible
newLog = console.log.conditionalCurry(false, 'never visible|' );
newLog('log visible'); // gives nothing, it works!
但是当我在Chrome 48.0.2564.109上测试代码并在firefox 44.0.2中出现问题时,我认为两种情况都是一样的。
据我所知,不知何故,这个'这个'当我在终端中使用节点时传递给函数conditionalCurry,是一个匿名函数,但在浏览器的情况下,这个'显示为一个名为' log'的函数,我相信这会破坏代码。
任何想法如何在浏览器中实现此功能?
提前致谢!!!
使用Bergi的解决方案,现在可以使用:Fiddle
答案 0 :(得分:1)
我会厌倦修改现有语言功能的原型,例如Function
。看起来你真的想要这些日志工具的实例,所以你也可以定义那个实例并以“经典”的意义使用它。
例如,让我们创建一个名为“Logger”的“类”(仅使用语言不可知术语)。记录器实例可以配置为显示带前缀的消息,有条件地将消息发送到日志,还可以半传统方式使用日志。
function Logger(display,prefix){
this.display = display == [][0] ? true : display;
this.prefix = prefix;
}
Logger.prototype.log = function(){
if(this.display){
[].splice.apply(arguments,[0,0,this.prefix])
console.log.apply(console,arguments);
}else{
console.log(this.prefix);
}
return this;
};
Logger.prototype.show = function(truthy){
this.display = !!truthy;
return this;
};
Logger.prototype.note = function(msg){
this.prefix = msg;
return this;
};
var newLog = new Logger(true,'always |');
newLog.log('show me');//always | show me
newLog.note('never show').show(false);
newLog.log('show me now');//never show
答案 1 :(得分:0)
这是执行上下文的问题。由于您将咖喱功能附加到功能原型','这个'关键字将引用您正在调用它的函数。在这种情况下,' log'在console.log中。
我不会修改原型,只需制作咖喱辅助功能:)
function curry(fn, ctx) {
var slice = Array.prototype.slice.call;
return function f() {
var x = slice(arguments);
// If we have enough arguments, call the function
// You can get the arity with the 'length' property
if (x.length >= fn.length) return fn.apply(ctx, x);
// If not, collect more arguments
return function () {
var y = slice(arguments);
return f.apply(null, x.concat(y));
}
}
}
// Trivial example
var curriedSum = curry(function(a, b, c) {
return a + b + c;
});
// this now works
curriedSum(1, 2, 3);
curriedSum(1)(2, 3);
curriedsum(1)(2)(3);
// for your use case
var curriedLog = curry(function(show, prefix, msg) {
if (! show) return;
return console.log(prefix + msg);
});
// Use like so
var neverLogs = curriedLog(false);
neverLog('Some Prefix|', 'some message') // never logs
var logWithPrefix = curriedLog(true, 'This is my prefix|');
logWithPrefix('wassup') // logs 'this is my prefix| wassup'
如果你需要强迫这个'将关键字作为特定对象,将该对象作为第二个参数传递。
curry(fn, context);