您问了很多问题,其中大部分是重复的。但是,我知道有时很难拼凑许多不同的答案来找到您自己问题的答案。将来,您应该避免在帖子中提出比问题更多的问题。这会让一些人不那么生气。
我将在代码内联添加一些 cmets
function logAndReturn(func) { // <------------┐
return function() { // <------------------┐ |
// `arguments` belongs to this function-┘ |
// NOT this one --------------------------┘
var args = Array.prototype.slice.call(arguments);
// `apply` expects an array but `arguments` is an object
// we call `slice` on `arguments` so that it can be converted to an array
var result = func.apply(null, args);
console.log('Result', result);
return result;
}
}
var addAndLog = logAndReturn(add);
实际上,JavaScript 比这要宽容得多。它不是一种类型化的语言,所以当我说apply expects 一个数组时,我有点撒谎。当然,它会很好,但如果你给它一个 array-like 对象,它也不会哭泣
function theHiddenTruthBehindArguments() {
console.log(arguments)
console.log(arguments.length)
}
theHiddenTruthBehindArguments(0,1,'abc')
// {"0":0,"1":1,"2":"abc"}
// 3
arguments 实际上是一个类数组 对象。它具有连续的数字键(以 0 开头)和 length 属性,这是将任何对象视为数组所需的所有信息。
所以这实际上可以工作
function logAndReturn(func) {
return function() {
// this works too !
var result = func.apply(null, arguments);
console.log('Result', result);
return result;
}
}
var addAndLog = logAndReturn(add);
为了回答你的最后一个问题,apply 以非常简单的方式炒锅……
let args = [1,3,4]
func.apply(null, args)
…(大部分)与…相同
func(1,3,4)
这个你可以阅读欺骗问题。您可能需要了解一些细节。
你给出的那个函数可以在 ES6 中更好地表达,我认为它对你来说不会那么混乱
function logAndReturn(func) {
// rest parameter ...args is the new way to express variadic functions
// (functions that take a variable number of arguments)
// all arguments given will be collected in a single `args` array
return function(...args) {
// spread syntax will expand the array to call `func`
// with all of the collected args
var result = func(...args)
console.log('Result', result)
return result
}
}