Javascript: 编写高阶函数以使用调用它的对象的上下文
Javascript: Write a higher-order function to use the context of the object from which it is called
我正在尝试编写一个向任何函数添加日志记录的函数。类似于:
function loggerise(f) {
return function() {
const r = f(...arguments)
console.log(r)
return r
}
}
除了上面的不行。
在此对象上测试:
const oracle = {
question:'',
ask: function(q) {this.question=q},
answer: function() {return 'Answer to '+this.question+' is 42'},
answerLog: loggerise(function() {return 'Answer to '+this.question+' is 42'})
}
oracle.ask('the universe');
alert(oracle.answer()); // correct result, no logging
alert(loggerise(()=>(42))()) // correct result and logging, not in object
alert(oracle.answerLog()); // wrong result and logging, in object
函数给出的结果Answer to undefined is 42
表明对象的上下文丢失了。我试图明确定义上下文,但我弄错了:
function loggerise(f) {
const that = this
return function() {
const r = f.apply(that,arguments)
console.log(r)
return r
}
}
给出了相同的错误结果,同样的一些变体也是如此。
调用函数的时候也需要传过来the value of this
,否则调用对象中的方法会丢失上下文
您可以将 the arguments
object 用于:
Function#apply()
function loggerise(f) {
return function() {
const r = f.apply(this, arguments);
console.log(r)
return r;
}
}
function loggerise(f) {
return function() {
const r = f.apply(this, arguments);
console.log(r)
return r;
}
}
const oracle = {
question:'',
ask: function(q) {this.question=q},
answer: function() {return 'Answer to '+this.question+' is 42'},
answerLog: loggerise(function() {return 'Answer to '+this.question+' is 42'})
}
oracle.ask('the universe');
console.log(oracle.answer());
console.log(loggerise(()=>(42))());
console.log(oracle.answerLog());
Function#call()
function loggerise(f) {
return function() {
const r = f.call(this, ...arguments);
console.log(r)
return r;
}
}
function loggerise(f) {
return function() {
const r = f.call(this, arguments);
console.log(r)
return r;
}
}
const oracle = {
question:'',
ask: function(q) {this.question=q},
answer: function() {return 'Answer to '+this.question+' is 42'},
answerLog: loggerise(function() {return 'Answer to '+this.question+' is 42'})
}
oracle.ask('the universe');
console.log(oracle.answer());
console.log(loggerise(()=>(42))());
console.log(oracle.answerLog());
Reflect.apply()
function loggerise(f) {
return function() {
const r = Reflect.apply(f, this, arguments);
console.log(r)
return r;
}
}
function loggerise(f) {
return function() {
const r = Reflect.apply(f, this, arguments);
console.log(r)
return r;
}
}
const oracle = {
question:'',
ask: function(q) {this.question=q},
answer: function() {return 'Answer to '+this.question+' is 42'},
answerLog: loggerise(function() {return 'Answer to '+this.question+' is 42'})
}
oracle.ask('the universe');
console.log(oracle.answer());
console.log(loggerise(()=>(42))());
console.log(oracle.answerLog());
这些之间没有太大区别。看你喜欢哪一个。
我正在尝试编写一个向任何函数添加日志记录的函数。类似于:
function loggerise(f) {
return function() {
const r = f(...arguments)
console.log(r)
return r
}
}
除了上面的不行。
在此对象上测试:
const oracle = {
question:'',
ask: function(q) {this.question=q},
answer: function() {return 'Answer to '+this.question+' is 42'},
answerLog: loggerise(function() {return 'Answer to '+this.question+' is 42'})
}
oracle.ask('the universe');
alert(oracle.answer()); // correct result, no logging
alert(loggerise(()=>(42))()) // correct result and logging, not in object
alert(oracle.answerLog()); // wrong result and logging, in object
函数给出的结果Answer to undefined is 42
表明对象的上下文丢失了。我试图明确定义上下文,但我弄错了:
function loggerise(f) {
const that = this
return function() {
const r = f.apply(that,arguments)
console.log(r)
return r
}
}
给出了相同的错误结果,同样的一些变体也是如此。
调用函数的时候也需要传过来the value of this
,否则调用对象中的方法会丢失上下文
您可以将 the arguments
object 用于:
Function#apply()
function loggerise(f) {
return function() {
const r = f.apply(this, arguments);
console.log(r)
return r;
}
}
function loggerise(f) {
return function() {
const r = f.apply(this, arguments);
console.log(r)
return r;
}
}
const oracle = {
question:'',
ask: function(q) {this.question=q},
answer: function() {return 'Answer to '+this.question+' is 42'},
answerLog: loggerise(function() {return 'Answer to '+this.question+' is 42'})
}
oracle.ask('the universe');
console.log(oracle.answer());
console.log(loggerise(()=>(42))());
console.log(oracle.answerLog());
Function#call()
function loggerise(f) {
return function() {
const r = f.call(this, ...arguments);
console.log(r)
return r;
}
}
function loggerise(f) {
return function() {
const r = f.call(this, arguments);
console.log(r)
return r;
}
}
const oracle = {
question:'',
ask: function(q) {this.question=q},
answer: function() {return 'Answer to '+this.question+' is 42'},
answerLog: loggerise(function() {return 'Answer to '+this.question+' is 42'})
}
oracle.ask('the universe');
console.log(oracle.answer());
console.log(loggerise(()=>(42))());
console.log(oracle.answerLog());
Reflect.apply()
function loggerise(f) {
return function() {
const r = Reflect.apply(f, this, arguments);
console.log(r)
return r;
}
}
function loggerise(f) {
return function() {
const r = Reflect.apply(f, this, arguments);
console.log(r)
return r;
}
}
const oracle = {
question:'',
ask: function(q) {this.question=q},
answer: function() {return 'Answer to '+this.question+' is 42'},
answerLog: loggerise(function() {return 'Answer to '+this.question+' is 42'})
}
oracle.ask('the universe');
console.log(oracle.answer());
console.log(loggerise(()=>(42))());
console.log(oracle.answerLog());
这些之间没有太大区别。看你喜欢哪一个。