18

I learned there are 2 types of creating objects. First: object literal notation and second: Object constructor. I have learned that there are also methods and functions, but I couldn't understand how to create a method in object literal notation? In object constructor I just write:

var bob = new Object();
bob.age = 30;
bob.setAge = function(newAge) {
  bob.age = newAge;
};

Can you please tell me how to do the same when writing object literal notation.

var bob = {
  age: 30
};
Ivar
  • 6,138
  • 12
  • 49
  • 61
GreedyAi
  • 2,709
  • 4
  • 29
  • 55
  • 7
    Please forget about w3schools. It's a terrible resource. Use MDN instead. And instead of `new Object()`, you would better simply use `{}`. – kapa Jul 05 '13 at 10:39
  • If you want to use functions on your object instances (like creating several person objects) then defining the same function for every object isn't realy effective. In JavaScript you can use constructor functions and set shared properties (like functions) on it's prototype: http://stackoverflow.com/questions/16063394/prototypical-inheritance-writing-up/16063711#16063711 – HMR Jul 05 '13 at 10:56
  • My code still doesn't work, should I write it here or create a new question? I am new at stackoverflow :) – GreedyAi Jul 05 '13 at 11:01
  • yea I understood that it wasn't effective, but I did it this way just to understand how methods and functions work on objects. but, thanks I am glad to learn more and will read about shared properties on it's prototype :) – GreedyAi Jul 05 '13 at 11:05
  • 6
    **NEVER use w3schools for documentation, most of it is wrong. Always use the MDN JavaScript documentation.** –  Aug 06 '16 at 07:00
  • I'll keep that in mind. Thank you! – GreedyAi Aug 08 '16 at 12:04
  • 1
    @JarrodRoberson Could you cite some examples of how W3Schools is mostly "wrong"? I agree W3Schools isn't the best source for learning to code. But it is not that bad. It's not designed to be a reference site or for learning all the nuances of a particular technology.. Think of it as a springboard for an introduced to various programming languages and standards for the web where one can quickly survey different technologies and even test them on their browser. W3Schools is what sparked my appreciation for coding. Sites like MDN and Stack Overflow are where I learn to master the craft. – Jules Manson Jul 07 '17 at 21:35
  • @JulesManson There is [some history](https://meta.stackoverflow.com/questions/280478/why-not-w3schools-com). – Ivar Jan 05 '21 at 16:06

7 Answers7

48

Syntactically, the change is very simple :

var bob = {
  age: 30,
  setAge: function (newAge) {
    bob.age = newAge;
  }
};

But as you can see, there's a problem : as in your code it uses the external bob variable so this wouldn't work if you change the value of the bob variable.

You can fix that with

var bob = {
  age: 30,
  setAge: function (newAge) {
    this.age = newAge;
  }
};

Note that at this point you should check whether what you need isn't, in fact, a class, which would bring some performance improvements if you have several instances.

Update: ECMAScript 6 now allows methods to be defined the same way regardless of whether they are in an object literal:

var bob = {
  age: 30,
  setAge (newAge) {
    this.age = newAge;
  }
};
Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • I think the question was only on how to get the same result as in the first snippet :-) Whether to usse `this` or a variable is discussed [here](http://stackoverflow.com/q/10711064) already – Bergi Jul 05 '13 at 10:46
  • My code still doesn't work, should I write it here or create a new question? (I am new at stackoverflow) :) – GreedyAi Jul 05 '13 at 11:02
  • You probably should ask a new question but this question should show your not working code (short enough) and explain why you think it doesn't work and what's the intended result. – Denys Séguret Jul 05 '13 at 11:04
  • 6
    The ECMAScript 6 update part is quite helpful - I was confused to see that kind of syntax in some code, but now I'm relaxed. However, the link seems dead. – ibic Jul 21 '17 at 03:58
  • @ibic Thanks for notifying me of the dead link. Unfortunately I don't find any good one to put in place so I just removed that last part about "maximally minimal classes" which was rather off-topic. – Denys Séguret Jul 21 '17 at 06:13
  • @DenysSéguret Strange thing is that if I google "maximally minimal classes javascript", the first result (a github gist) refers to exactly your (previous) link, now an "official" document seems hard to come by. It's a good term to know (for communication / searching). – ibic Jul 21 '17 at 06:49
4

Its nothing different and as easy as

var bob = {
    age:     30,
    setAge:  function( newAge ) {
        this.age = newAge;
    }
};

Alternatively, you can create a real setter function either by invoking Object.defineProperty() or as simple as

var bob = {
    age:       30,
    firstName: 'j',
    lastName:  'Andy',
    set setName( newName ) {
        var spl = newName.split( /\s+/ );
        this.firstName = spl[ 0 ];
        this.lastName  = spl[ 1 ];
    }
}

Where you could go like

bob.setName = "Thomas Cook";  // which sets firstName to "Thomas" and lastName to "Cook"
jAndy
  • 231,737
  • 57
  • 305
  • 359
  • 2
    You wouldn't call a setter property `setX` :-) – Bergi Jul 05 '13 at 10:42
  • @Bergi I knew somebody would complain :p – jAndy Jul 05 '13 at 10:42
  • 1
    @jAndy Seriously, it's ugly :) – Denys Séguret Jul 05 '13 at 10:46
  • I thought the point of SO was to teach generally accepted conventions of coding in addition to coding concepts. Having a setter called setAge doesn't properly explain how it abstracts the property, and teaches a new coder a terrible convention. It should be `set age: (value) { this._age = value; }`. why not just edit your answer to fix it? – Steven Moseley Jul 05 '13 at 11:11
  • @StevenMoseley I don't feel that the use of underscored properties to pretend privacy is anything like *accepted convention*. But if its that important I will update the example. – jAndy Jul 05 '13 at 11:32
  • @jAndy - The lack of scope in JS has led to the use of underscores as a convention to identify members intended for internal use only. I get why you don't like it, but it is still a convention. – Steven Moseley Jul 05 '13 at 11:55
  • @StevenMoseley if you will excuse me, but its not. Neither is it to even use underscored identifiers for that reason. Closures provide a much more convenient way to mimic privacy (either in singleton patterns or constructor functions) and is by far more valid convention. – jAndy Jul 05 '13 at 12:00
  • @jAndy - Note I didn't mention scope in my comment. I agree with you that closures allow better scoping in JS (even though the technique is itself a hack). However, it is most definitely an accepted convention (albeit not by everyone) to use an underscore prefix to define public members intended for internal use only in languages without explicit scope definition (e.g. php4, python, js). http://stackoverflow.com/questions/1301346/the-meaning-of-a-single-and-a-double-underscore-before-an-object-name-in-python – Steven Moseley Jul 05 '13 at 16:41
2

The last code you posted is missing a comma. Also, you don't need a ';' after a function definition of an object's property. Like this:

var object2 = {
name: "Fred",
age: 28,
club: "Fluminense",
bio2: function (){
    console.log(this.name +" is "+ this.age + " years old and he is playing in "+             this.club);
    }
};
Fafoon
  • 181
  • 1
  • 3
  • That has been moved to another question: http://stackoverflow.com/questions/17487840/whats-wrong-with-my-code-in-creating-a-method-in-object-literal-notation – Bergi Jul 05 '13 at 11:39
1

This is the way to solve this exercise using literal object creation method:

var setAge = function (newAge) {
  this.age = newAge;
};

var bob = new Object();
bob.age = 30;
bob.setAge = setAge;

var susan = {
    age: 25,
    setAge: setAge
}

susan.setAge(35);
mikefirsov
  • 11
  • 2
1

If you want encapsulation, you might use the following syntax(self-executing function). Here age is not accessible from the outside of the object bob.

var bob = (function() {
    //...private
    var age = 30;

    function setAge(newAge) {
        age = newAge;
    };

    function getAge() {
            return age;
        }
    // Public api
    return {
        setAge: setAge,
        getAge: getAge
    }
}());
bob.setAge(50);
alert(bob.getAge());

jsfiddle: http://jsfiddle.net/61o9k98h/1/

Razan Paul
  • 13,618
  • 3
  • 69
  • 61
1

Starting with ECMAScript 2015, a shorter syntax for method definitions on objects initializers is introduced. It is a shorthand for a function assigned to the method's name


const bob = {
    age: 30,
    setAge(age) {
        this.age = age;
    },
};
alert(bob.age); // 30
bob.setAge(63); // set age = 63
alert(bob.age); // 63

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions

Mamé
  • 59
  • 5
0

Like this:

var bob = {
    age: 30,
    setAge: function (age) {
        this.age = age;
    }
}
alert(bob.age); // 30
bob.setAge(45); // set age = 45
alert(bob.age); // 45
Nono
  • 6,986
  • 4
  • 39
  • 39