最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

oop - Passing keyvalue objects as a parameter in a Javascript constructor - Stack Overflow

programmeradmin10浏览0评论

I'm setting up an object constructor and would like to pass an key/value object as a parameter. I was wondering what would be the correct way to do so? Right now I'm just passing the keys as the parameters:

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

Although this works, ing from a Ruby background it only felt right to pass the object itself and assign the it's values in the initializer. This was the best equivalent I could think of:

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

Is there a way to do this in Javascript? The way I have things written now makes me feel as if I'm bloating my constructer's list of parameters (unless this is the right way to do this).

I'm setting up an object constructor and would like to pass an key/value object as a parameter. I was wondering what would be the correct way to do so? Right now I'm just passing the keys as the parameters:

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

Although this works, ing from a Ruby background it only felt right to pass the object itself and assign the it's values in the initializer. This was the best equivalent I could think of:

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

Is there a way to do this in Javascript? The way I have things written now makes me feel as if I'm bloating my constructer's list of parameters (unless this is the right way to do this).

Share Improve this question edited Mar 20, 2016 at 12:45 Carl Edwards asked Mar 20, 2016 at 12:39 Carl EdwardsCarl Edwards 14.5k12 gold badges66 silver badges131 bronze badges 1
  • Can pass in one object argument instead of multiple primitives if that is what you are asking. Not really clear what you want to do – charlietfl Commented Mar 20, 2016 at 12:49
Add a ment  | 

4 Answers 4

Reset to default 2

You can pass an object just like you did in your ruby class.

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

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

Above will create the same output as before. It's worth to mention that ecmascript 2015 brought classes to javascript - so you could also write it like this:

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

Above we're using an empty object as default parameter, which is also an es2015 feature.

If you want to have default key names, something like this will make it

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

Do you mean something like this?

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

As others have pointed out, it is possible to pass an object as an argument.

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

The problem with this naive approach is that Objects in JavaScript are mutable. If you assign the Object like above, your object state can be mutated accidentally. For example:

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

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

Here you mutate ratings after diner was created, and you accidentally set diner.serviceRatings.poor to 12.

You can protect your code from this by copying the values of your object:

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

Object.assign() copies every property from seviceRatings to {}; this way later modifications to the other object do not affect your member property.

If you are using ES2015, you can use object destructuring, which has additional benefits: it makes your expected data structure explicit; and allows you to specify default values:

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

Edit: as seen in another answer, if you are using ES2015, you might as well as use the class syntactic sugar:

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

arguments will contain all the parameters passed to the function as a list.

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

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

}());
发布评论

评论列表(0)

  1. 暂无评论