关于Javascript:Javascript – 带有可选参数作为对象的函数?

Javascript - function with optional parameters as object?

我需要一个函数,它的参数是一个对象,如果我把它留空,它将加载默认值。

就像是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function loadMap(args) { //args is an object and its optional

   //this is what I want to do, test args and load defauts if necesary
   /*
   pseudocode:
   if args.latitude is not set then
       give it a default value

   if args.longitude is not set then
       give it a default value

    end pseudocode */


   alert("Latitude is"+args.latitude );
   alert("Longitude is"+args.longitude );
}

//outputs the default values
loadMap();

//outputs custom values
loadMap({latitude:"x.xxxx", longitude:"-x.xxxx"});

//and should work too and output one default and one custom value
loadMap({latitude:"x.xxxx"});

我在这个问题中找到了这个解决方案(有没有更好的方法在Javascript中执行可选的函数参数?)但它需要jQuery:
http://jsfiddle.net/xy84kwdv/

它几乎是我想要的,但我不想依赖于jquery函数。


当然这个问题已经超过3年了(2018-03-02)。我搜索了这个主题,但我得到的大部分问题和排名最高的答案似乎都已经过时了,比如这个,这个,这个或者这个。

目前,许多浏览器都支持ES6 / ECMAScript 2015(第6版ECMAScript)。为了兼容性,您可以使用WebpackJs(或其他打包程序)和BabelJs(或其他编译器)将ES6代码编译并打包到ES5。这个问题的ES6版本答案可能是对象解构。

1
2
3
4
5
6
7
8
9
10
11
function drawES2015Chart({size = 'big', cords = {x: 0, y: 0}, radius = 25} = {}) {
    console.log(size, cords, radius);
    // do some chart drawing
}

drawES2015Chart({cords: {x: 18, y: 30}, radius: 30});

function fn(requiredArg, {optionalArg = 'Default Value', a = 1, b ={some: 'object'}} = {}){
    // Do with destructured values: requiredArg, optionalArg, a, and b.
    console.log(requiredArg, optionalArg, a, b);
}

所以对于你的问题,它将是:

1
2
3
4
5
6
7
function loadMap({latitude ="x.xxxx", longitude ="-x.xxxx"} = {}) {
    console.log('latitude is:', latitude, 'and longitude is:', longitude);
    console.log(`latitude is: ${latitude}, and longitude is: ${longitude}`);
}

// Call the function.
loadMap({latitude:"1.2345", longitude:"-6.7890"});


你在寻找类似的东西:

1
2
3
4
5
6
7
8
9
function loadMap(args) {
    args = args || {};
    args.latitude = args.latitude ||"X.XXX";
    args.longitude = args.longitude ||"Y.YYY";
    alert(args.latitude);
    alert(args.longitude);
};

loadMap({latitude:"custom_latitude"});


这使得参数对象可选,并使单个属性可选:

1
2
3
4
5
6
7
8
9
10
var defaults = { latitude: x, longitude: y };
function loadMap(args) {
    args = args || {};
    for (var key in defaults) {
        if (!(key in args)) {
            args[key] = default[key];
        }
    }
    ...
}


Overkill,介绍完整的对象克隆(ECMAScript 5.1)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
function cloneOwnProperties(A, B, overwrite) { // this is shallow
    var i, p;
    if (!(A instanceof Object)) {
        if (undefined === A) A = {};
        else throw new TypeError('cloneOwnProperties called on non-object');
    }
    if (!B) B = {};
    p = Object.getOwnPropertyNames(A);
    for (i = 0; i < p.length; ++i)
        if (overwrite || !(p[i] in B))
            Object.defineProperty(B, p[i], Object.getOwnPropertyDescriptor(A, p[i]));
    return B;
}

// and for completeness
function cloneObject(obj_in, clone_seal, clone_frozen) {
    var obj_out;
    if (!(obj_in instanceof Object))
        throw new TypeError('cloneObject called on non-object');
    obj_out = Object.create(Object.getPrototypeOf(obj_in));
    cloneOwnProperties(obj_in, obj_out, true);
    if (clone_seal && Object.isSealed(obj_in)) Object.seal(obj_out);
    if (clone_frozen && Object.isFrozen(obj_in)) Object.freeze(obj_out);
    return obj_out;
}
// back on topic

现在您可以使用它来设置一些默认值

1
2
3
4
5
6
7
8
9
function foo(bar) {
    bar = cloneOwnProperties(bar, {
        fizz: true,
        buzz: false
    }, true);
    return bar;
}

foo({buzz: 'user_value'}); // {fizz: true, buzz:"user_value"}

如何在javascript中重载函数?
查看OP的第二个答案。它提供了使用jQ的替代方案。

注意:如果args通过,则Kim的代码将导致逻辑??错误,但计算结果为true。
更好的解决方法:
optionalArg =(typeof optionalArg ==="undefined")?"defaultValue":optionalArg;