javaScript - pass object as function argument

2020-06-23 09:21发布

问题:

I want to use an object as function argument. When I define an object outside fucntion and then pass it as an argument, it works fine:

var obj = {
  a: 0
}

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

foo() //0

But when I pass an object directly, it doesen't work:

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

An object doesent seem to be a legal argument. How do I fix it?

回答1:

ES6 supports parameters destructuring. You can use:

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

However usually it is useful when you have multiple parameters:

// 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)
}

Only old IE doesn't support it.

But when I pass an object directly, it doesn't work:

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

You cannot pass parameters this way or make initialization of a default parameter. Furthermore, this in you case will refer to the parent object, so this.arguments.a doesn't make sense as in most cases it will refer to window object.

With parameters destructuring you may use default parameters, so your code will look:

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

Still, any efforts to call it without parameter will result in error as JS will try to resolve property of undefined

You may use another default parameter assignment to resolve the issue. When you really want to call bar() without parameters and have default value for destructured parameter you should use something like:

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

Just don't forget that it is not widely supported by browsers, so you will have to use transpiler to convert your ES6 code one supported by browser.

Most popular transpilers are Babel and Typescript.



回答2:

Cause this has nothing todo with the variables passed. Dont use it here. Simply do:

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

     bar({});//0
     bar();//0
     bar({a:10});//10



回答3:

First, it appears that you are combining how to declare a function parameter with how to call a function and pass it a parameter with this code:

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

Next, when accessing arguments, just use the parameter name, not this. this is used to reference the invocation context object, not function parameters. The invocation context object is essentially the object that was responsible for causing the function to be invoked in the first place. It can also point to an object that was explicitly set to replace the native object that would have been the context object. And, in the right circumstances, it can point to the Global (window) object or be undefined. this is typically confusing for a lot of JavaScript developers. Here's a link to more information on this.

So your code should be:

// 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});

Now, you can in fact supply a default value for a function and this would be how to do that:

// 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:

None of the answers have actually tried to address the issue here so I thought I might have a go.

You ask: "I want to use an object as function argument." And yet your first example doesn't show you doing this. You are not passing in an object as a function argument. What you are doing is declaring a variable under window (assuming this is browser code) and then logging that variable's value to the console. Because this is context and this is defined by the way the function is called, in this instance the context is window and so your code works.

You second code example compounds the errors you're making in the first example. arguments is scoped locally to the function. It doesn't need this in front of it. And you can't access it like it's an object because arguments is an array-like structure. You would access it like this: arguments[0].a assuming you're passing the object into your function like this: bar({a: 1}).

JavaScript context and scope can be a very difficult concept to get your head around. I'm a pretty seasoned JS developer and it still catches me out occasionally, so don't be disheartened. This article is very good at explaining context (and function scope) and I think you would benefit from reading it.