2017-07-04 28 views
0

我发现,使用下面的NodeJS功能的物品适用于:调用带有一个数组

var path = require('path'); 

var _root = path.resolve(__dirname, '..'); 

function root(args) { 
    args = Array.prototype.slice.call(arguments, 0); 
    return path.join.apply(path, [_root].concat(args)); 
} 

exports.root = root; 

,因为我不知道如何使用callapply,我做了一些测试/研究,但还是有一些我没有得到:return声明。

我试图通过

return path.join([_root].concat(args)) 

来取代它,但我得到了:

抛出新类型错误;(+ 检查(路径) '路径必须是一个字符串收到'。)

好了,这样传递给path.join参数必须是一个string,不够公平,但apply功能并将其作为一个数组,所以它怎么能工作呢?

为了验证这一点,我创建了这个简单的功能:

function foo (arg) { console.log(arg); } 

而且我把它叫做这样:

foo.apply(foo, ["plop", "plip"]) 

但我只是得到“扑通”一声,所以我不知道如何path.join正在工作,如果它只获取数组的第一项。我也尝试显示arguments,但后来我得到了一个数组,而不是一个字符串。

基本上,我不明白为什么数组作为参数被接受为字符串,而不是当我直接调用path.join

回答

3

假设您有一个const arr = [ 'a', 'b', 'c' ]的数组。
当您拨打path.join.apply(path, arr)时,它会传播并将与呼叫
path.join('a', 'b', 'c')相同。

.apply传播参数。所以,你的函数应该是这个样子function foo(arg1, arg2) { /* ... */ }

如果你想传递给函数在一个变量的所有参数,使用arguments像这样:

function test(arg1, arg2) { 
    console.log(arg1, arg2); 
    console.log(arguments); 
} 

test.apply(null, [ 'a', 'b' ]); 

.call,另一方面只是调用一个函数分离的参数。 所以在这里我们的例子中,你会怎么做test.call(null, 'a', 'b');


所以我为什么要使用callapply嗯,可能有很多更多的理由比我要在这里提到的,但

  1. 可以动态调用功能,决定调用基于变量其中之一。
  2. 您可以定义另一个上下文。第一个参数是您可以传递的上下文,它在函数体内表示为this

以下是applycall的文档页面。

+0

绝对正确。我只想补充一点,即应用和调用之间的唯一区别就是如何传递参数。应用 - 数组和呼叫 - 只用逗号分隔。 – Lazyexpert

+0

所以,如果我理解的很好,它的工作原理是因为数组在'path.join'的参数中传播。但在这种情况下,这个函数如何访问这些参数,因为它们的数字可以是动态的('path.join('a','b')'或'path.jon('a','b','c' )')。我猜它使用'arguments',它是一个类似数组的,所以当我直接传递一个真实的数组时,为什么它不工作?是因为在第一种情况下,'arguments'将包含字符串项目,而在第二种情况下,它将包含一个字符串数组? – ssougnez

+0

因为'path'是一个数组。它不使用参数作为输入,而只使用第一个参数作为“胶水”。看看[在MDN上的示例](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join) – lumio