繁体   English   中英

将键/值对象作为参数传递给Javascript构造函数

[英]Passing key/value objects as a parameter in a Javascript constructor

我正在设置一个对象构造函数,并希望将键/值对象作为参数传递。 我想知道这样做的正确方法是什么? 现在,我只是将键作为参数传递:

(function() {
    function Venue(name, poor, satisfactory, excellent) {
        this.name = name;
        this.serviceRatings = {
            poor: poor,
            satisfactory: satisfactory,
            excellent: excellent
        };
    }

  var dining = new Venue("dining", .1, .15, .2);

  console.log(dining["serviceRatings"]["satisfactory"] // .15
}());

尽管这是可行的,但它来自Ruby背景,只是传递对象本身并在初始化程序中分配其值才是正确的选择。 这是我能想到的最好的选择:

class Venue
  def initialize(name, serviceRatings = {})
    @name = name
    @poor = serviceRatings[:poor]
    @satisfactory = serviceRatings[:satisfactory]
    @excellent = serviceRatings[:excellent]
  end
end

有没有办法用Javascript做到这一点? 现在,我编写事情的方式使我感到好像在膨胀构造函数的参数列表(除非这正确的方法)。

你的意思是这样吗?

(function() {
        function Venue(name, serviceRatings) {
            this.name = name;
            this.serviceRatings = serviceRatings;
        }

        var dining = new Venue("dining", {
            poor:.1,
            satisfactory:.15,
            excellent:.2
        });

        console.log(dining["serviceRatings"]["satisfactory"]) // .15
    }());

您可以像在ruby类中一样传递对象。

function Venue(name, options) {
    this.name = name;
    this.serviceRatings = options;
}

var dining = new Venue("dining",{
        poor: .1,
        satisfactory: .15,
        excellent: .2
    });

上面将创建与以前相同的输出。 值得一提的是ecmascript 2015将类引入了javascript-因此您也可以这样编写:

class Venue {
    constructor(name, options = {}) {
        this.name = name;
        this.serviceRatings = options;
    }
}

上面我们使用一个空对象作为default parameter ,这也是es2015的功能。

如果您想使用默认的键名,可以使用类似的方法

class Venue {
    constructor(name, options = {}) {
        this.name = name;
        this.serviceRatings = Object.assign({
           poor: undefined,
           satisfactory: undefined,
           excellent: undefined
        }, options);
    }
}

正如其他人指出的那样,可以将一个对象作为参数传递。

// naive ES5 version
function Venue(name, serviceRatings) {
    this.name = name;
    this.serviceRatings = serviceRatings;
}

这种幼稚的方法的问题在于JavaScript中的对象是可变的。 如果按上述方式分配对象,则对象状态可能会意外更改。 例如:

var ratings = { poor: 0, satisfactory: 2, excellent: 8 };
var diner = new Venue('diner', ratings);

ratings.poor = 12;
var burgerJoint = new Venue('my burgers', ratings);

在这里,您在创建晚餐之后更改了评分,并且您不小心将diner.serviceRatings.poor设置为12。

您可以通过复制对象的值来保护您的代码:

// improved with Object.assign
function Venue(name, serviceRatings) {
    this.name = name;
    this.serviceRatings = Object.assign({}, serviceRatings);
}

Object.assign()将每个属性从seviceRatings复制到{}; 这样,以后对另一个对象的修改不会影响您的成员属性。

如果使用ES2015,则可以使用对象分解,这还有其他好处:它使您期望的数据结构明确; 并允许您指定默认值:

// ES2015 version with explicit parameters and default values
function Venue(name, { poor = 0, satisfactory = 0, excellent = 0 }) {
    this.name = name;
    this.serviceRatings = { poor, satisfactory, excellent };
}

编辑:如另一个答案所示,如果您使用的是ES2015,则不妨使用类语法糖:

// ES2015 version using class definition
class Venue
    constructor (name, { poor = 0, satisfactory = 0, excellent = 0 }) {
        this.name = name;
        this.serviceRatings = { poor, satisfactory, excellent };
    }    
}

参数将包含作为列表传递给函数的所有参数。

(function() {
    function Venue() {
        console.log(arguments);
    }

    var dining = new Venue("dining", .1, .15, .2);

}());

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM