【问题标题】:javaScript - pass object as function argumentjavaScript - 将对象作为函数参数传递
【发布时间】:2018-02-23 18:42:52
【问题描述】:

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

var obj = {
  a: 0
}

function foo(obj){
  console.log(this.obj.a); 
}

foo() //0

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

function bar({a: 0}){
  console.log(this.arguments.a)
}
// Uncaught SyntaxError: Unexpected number

一个对象似乎不是一个合法的论点。我该如何解决?

【问题讨论】:

  • this 只是上下文!!!不要用它来访问变量。
  • 您正在混合函数调用和函数定义。参数在函数调用中传递,它们没有在函数定义的参数列表中获取它们的值。
  • 您完全误解了javascript中参数和变量的工作方式。对参数和变量名重复使用相同的名称会使您感到困惑。您可以将对象作为参数传递,但不能在函数定义中定义它。
  • 您的推论有误。在第一个示例中,您甚至没有将值传递给 foo。所以this.obj实际上不能引用参数obj。在第一个示例中使用function foo(){ console.log(this.obj.a); }(注意:无参数),您会发现它仍然可以正常工作。所以this.obj与参数obj无关。你需要做两件事:Learn more about functionslearn how this works
  • 很遗憾这里没有一个答案试图解释上下文,因为这可能有助于消除很多混乱。

标签: javascript function object


【解决方案1】:

ES6 支持参数解构。 您可以使用:

function bar({a}){
    console.log(a)
}

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

// you pass option to a function old way
function oldOps(option){
    var protocol = option.protocol;
    var method = option.method;
    var port = option.port;
    console.log(port);
}
// new and more readable way
function newOps({protocol, method, port}){
    console.log(port)
}

只有老的IE不支持。

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

function bar({a: 0}){
  console.log(this.arguments.a)
}

您不能以这种方式传递参数或初始化默认参数。此外,在您的情况下,this 将引用父对象,因此 this.arguments.a 没有意义,因为在大多数情况下它将引用 window 对象。

通过参数解构,您可以使用默认参数,因此您的代码如下所示:

function bar({a = 0}){
    console.log(a)
}
bar({}) // 0

不过,任何不带参数的调用都会导致错误,因为 JS 会尝试解析 undefined 的属性

您可以使用另一个默认参数分配来解决此问题。当你真的想在没有参数的情况下调用bar() 并且为解构参数设置默认值时,你应该使用类似的东西:

function bar({a = 0} = {}){/*...*/}

请不要忘记浏览器并不广泛支持,因此您必须使用转译器将您的 ES6 代码转换为浏览器支持的代码。

最流行的转译器是BabelTypescript

【讨论】:

  • 虽然这是对的,但我看不出这对 OP 有何帮助。
  • @FelixKling 我添加了详细信息
  • 我仍然认为 OP 对函数调用的工作方式存在根本性的误解(仔细阅读问题)。在这种情况下谈论解构是没有帮助的,即使他们接受了答案。我怀疑他们是否理解这是什么意思。
  • 如果没有参数调用你的函数会抛出错误,因为它没有指定默认值。应该是function bar(a = {a:0}){...
  • @scott marcus 不应该。那么 a 就是一个对象。
【解决方案2】:

没有一个答案实际上试图解决这里的问题,所以我想我可以试一试。

你问:“我想使用一个对象作为函数参数。”然而你的第一个例子并没有显示你这样做。您将对象作为函数参数传递。您正在做的是在window 下声明一个变量(假设这是浏览器代码),然后将该变量的值记录到控制台。 因为this上下文,而this是由函数调用的方式定义的,在这种情况下上下文是window这样你的代码就可以工作了。

您的第二个代码示例加重了您在第一个示例中所犯的错误。 arguments 的作用域是函数的本地范围。它前面不需要this。而且你不能像对象一样访问它,因为arguments 是一个类似数组的结构。您可以像这样访问它:arguments[0].a 假设您将对象传递给您的函数,如下所示:bar({a: 1})

JavaScript 上下文和范围可能是一个很难理解的概念。我是一位经验丰富的 JS 开发人员,但它仍然偶尔会引起我的注意,所以不要灰心。 This article is very good at explaining context (and function scope) 我认为你会从阅读中受益。

【讨论】:

    【解决方案3】:

    首先,您似乎将如何声明函数参数与如何调用函数并使用以下代码传递参数:

    function bar({a: 0}){
      console.log(this.arguments.a)
    }
    

    接下来,访问参数时,只使用参数名称,而不是thisthis 用于引用调用上下文对象,而不是函数参数。调用上下文对象本质上是负责导致函数首先被调用的对象。它还可以指向一个对象,该对象被显式设置为替换本来是上下文对象的本机对象。并且,在适当的情况下,它可以指向全局 (window) 对象或 undefinedthis 通常会让许多 JavaScript 开发人员感到困惑。这里是 a link 以了解有关 this 的更多信息。

    所以你的代码应该是:

    // Declare the function and set up a named parameter
    function bar(someObj){
      console.log(someObj)
    }
    
    // Call the function and pass an object literal:
    bar({a: 0});

    现在,您实际上可以为函数提供默认值,这就是如何做到这一点:

    // Establish an object with an `a` property with a value of "Hello"
    // as the default value of the function's argument
    function bar(obj = {a: "Hello"}){
      console.log(obj);
    }
    
    bar();  // Default value of parameter will be used
    bar({a:"Goodbye"}); // Passed value will be used

    【讨论】:

      【解决方案4】:

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

           function bar({a = 0} = {}){
             console.log(a)
           }
      
           bar({});//0
           bar();//0
           bar({a:10});//10

      【讨论】:

      • 在 FF 中。乔纳斯,你应该测试一下。
      • @andy 是的,我应该。然而,我 90% 的时间都在 AFK,所以我并不总是能够这样做。
      猜你喜欢
      • 2012-05-30
      • 2012-06-12
      • 2019-08-29
      • 2012-03-07
      • 2014-06-07
      • 1970-01-01
      • 2017-12-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多