5

我想使用一个对象作为函数参数。当我在函数外定义一个对象,然后将其作为参数传递时,它工作得很好:

var对象={a: 0个}函数foo(obj){控制台.log(this.obj.a);}foo()//0

但当我直接通过一个物体时,它就不起作用了:

功能栏({a:0}){console.log(this.arguments.a)}//未捕获语法错误:意外数字

一个物体似乎是一个合法的论点。我该如何修复它?

7
  • 1
    只是上下文!!!不要用它来访问变量。 评论 2017年9月14日17:14
  • 您混合了函数调用和函数定义。参数是在函数调用中传递的,它们没有在函数定义的参数列表中获取值。
    – 泰穆
    评论 2017年9月14日17:16
  • 您完全误解了javascript中参数和变量的工作方式。重复使用相同的参数和变量名会让您感到困惑。可以将对象作为参数传递,但不能在函数定义中定义它。 评论 2017年9月14日17:17
  • 你扣错了。您甚至没有将值传递给foo公司在第一个示例中。所以this.obj(此对象)不能实际引用参数 对象.使用函数foo(){console.log(this.obj.a);}(注意:没有参数)在第一个示例中,您会发现它仍然可以正常工作。所以this.obj(此对象)与参数无关对象。你需要做两件事:了解有关函数的更多信息了解如何作品. 评论 2017年9月14日17:17
  • 1
    很遗憾,这里并没有一个答案试图解释上下文,因为这可能有助于消除很多困惑。
    – 安迪
    评论 2017年9月14日17:30

4个答案4

重置为默认值
11

ES6支持参数销毁。您可以使用:

功能栏({a}){控制台.log(a)}

但是,当您有多个参数时,它通常很有用:

//你用老方法将选项传递给函数函数oldOps(选项){var协议=选项协议;var方法=option.method;var端口=option.port;console.log(端口);}//新的更可读的方式函数newOps({协议、方法、端口}){console.log(端口)}

只有旧的IE不支持它。

但当我直接传递对象时,它不起作用:

功能栏({a:0}){console.log(this.arguments.a)}

不能以这种方式传递参数或初始化默认参数。此外,在您的示例中,将引用父对象,因此这是一个论据。没有意义,因为在大多数情况下,它会提到窗口对象。

在参数破坏的情况下,您可以使用默认参数,因此您的代码将如下所示:

功能栏({a=0}){控制台.log(a)}条({})//0

尽管如此,任何不带参数调用它的操作都会导致错误,因为JS将尝试解析未定义

您可以使用另一个默认参数赋值来解决此问题。当你真的想打电话的时候bar()如果没有参数,并且破坏参数具有默认值,则应使用类似以下内容:

功能栏({a=0}={}){/*…*/}

别忘了浏览器并不广泛支持它,所以您必须使用transpiler转换浏览器支持的ES6代码。

最受欢迎的转发器是巴别塔打字稿.

14
  • 虽然这是正确的,但我看不出这对OP有什么帮助。 评论 2017年9月14日17:20
  • @FelixKling I添加了详细信息 评论 2017年9月14日17:41
  • 4
    我仍然认为OP对函数调用的工作原理有一个基本的误解(请仔细阅读问题)。在这种情况下,谈论破坏是没有帮助的,尽管他们接受了这个答案。我怀疑他们是否理解这是怎么回事。 评论 2017年9月14日17:43
  • 如果调用时没有参数,函数将抛出错误,因为它没有指定默认值。应该是这样的功能栏(a={a:0}){。。。 评论 2017年9月14日17:51
  • @斯科特·马库斯不,不应该。那么a就是一个对象。 评论 2017年9月14日17:56
5

原因与传递的变量无关。不要在这里使用它。只需做:

功能栏({a=0}={}){控制台.log(a)}酒吧({})//0bar()//0棒材({a:10})//10

2
  • 在FF.Jonas中,你应该测试一下。
    – 安迪
    评论 2017年9月14日17:44
  • @安迪,是的,我应该。然而,我每天90%的时间都在AFK上,所以我并不总是能够做到这一点。 评论 2017年9月14日17:49
4

所有的答案都没有真正解决这个问题,所以我想我可以试试。

你问:“我想用一个对象作为函数参数。”然而,你的第一个例子并没有显示你这样做。你是将对象作为函数参数传入。你怎么了正在声明下的变量窗口(假设这是浏览器代码),然后将该变量的值记录到控制台。因为 上下文由函数的方式定义打电话,在本例中,上下文是窗口因此,您的代码可以正常工作。

您的第二个代码示例复合了您在第一个示例中所犯的错误。论据在本地作用域为函数。它不需要你不能像访问对象一样访问它,因为论据是一个类似阵列的结构。您可以这样访问它:参数[0]。假设您将对象传递到函数中,如下所示:条形图({a:1}).

JavaScript上下文和范围可能是一个很难理解的概念。我是一个经验丰富的JS开发人员,偶尔也会被发现,所以不要灰心。本文非常擅长解释上下文(和功能范围)我认为你会从中受益。

2

首先,您似乎将如何声明函数参数与如何调用函数以及如何使用以下代码传递参数结合在一起:

功能栏({a:0}){console.log(this.arguments.a)}

接下来,当访问参数时,只使用参数名,而不是.用于引用调用上下文对象,而不是函数参数。调用上下文对象本质上是负责首先调用函数的对象。它还可以指向一个对象,该对象被明确设置为替换本应是上下文对象的本机对象。在适当的情况下,它可以指向全球(窗口)对象或是未定义.对于许多JavaScript开发人员来说,这通常是令人困惑的。这里是链接有关的更多信息.

因此,您的代码应该是:

//声明函数并设置命名参数功能栏(someObj){console.log(someObj)}//调用函数并传递对象文字:条({a:0});

现在,您实际上可以为函数提供默认值,具体操作如下:

//建立一个具有值为“Hello”的`a`属性的对象//作为函数参数的默认值功能栏(obj={a:“Hello”}){控制台日志(obj);}bar();//将使用参数的默认值bar({a:“再见”});//将使用传递的值

你的答案

单击“发布您的答案”,表示您同意我们的服务条款并确认您已阅读我们的隐私政策.

不是你想要的答案吗?浏览标记的其他问题问你自己的问题.