1

I'm new to node.js, but wrote Javascript for many years, and I stumbled upon a pattern, that I don't understand: A Flag that sets a modifier on the object.

For instance here socket.io docs:

Flag: 'broadcast'

Sets a modifier for a subsequent event emission that the event data will only be broadcast to every sockets but the sender.

var io = require('socket.io')();
    io.on('connection', function(socket){
        socket.broadcast.emit('an event', { some: 'data' }); // everyone gets it but the sender
});

Here socket is an object, and broadcast is a property of that object, while socket.broadcast is that same object with a modifier set ?!

How is it possible that accessing the property of an objet returns the object itself ?

Is this a feature of Javascript that I ignored for years? Or is this some new feature of ES6 that I'm not aware of ? Or is this a coding pattern specific to node ?
And how does it work / is it achieved ?

Edit: even though the other question is about the same exerpt in the docs, it is very different. My question is about the background in Javascript, while the other one is about the wording in the docs. The answers also are very different for this reason.

1

2 Answers 2

4

I saw your question and was intrigued, so had a look in the socket.io source.

You can see the flag logic here.

flags.forEach(function(flag){
  Object.defineProperty(Socket.prototype, flag, {
    get: function() {
      this.flags[flag] = true;
      return this;
    }
  });
});

It's using a descriptor to define a property getter, which internally sets the flag and returns the object instance.

Interesting stuff.

Sign up to request clarification or add additional context in comments.

Comments

0

Lorenz, this is not something that is new to javascript. The method is able to do some mutation to its object, and then return that same object from the method that mutates it. By doing this, it is possible to create a long chain of commands in order to easily accomplish a task. Here is an example:

function person () {
    this.name = 'henry';
  this.withName = function (newName) {
    this.name = newName;
    return this;
  }
  this.printName = function () {
    console.log(this.name);
  }
}

var me = new person ();

me.printName();

me.withName('myNewName').printName();

me.printName();

From this example, you can see that the method "withName" mutates the object and then returns the object itself. From this point, you can then call another one of the object's methods (i.e., printName). From this point forward, the new value of name is 'myNewName'.

Please note that this is not a good practice to mutate an object in this way. The chaining of commands is normally a good concept in functional programming, but the chaining of commands ought to be immutable.

Therefore, the best way to utilize this concept of returning an object like the initial object from a method is to first create a copy of the initial object, then mutate the copy, then return the copy from the method. This will make things much easier to understand and to debug.

I hope this helps.

3 Comments

You're right. If there were parentheses after broadcast, like this socket.broadcast()..., I would not ask the question, because broadcast would be a method of the object.
I think you're confusing a.b.c with a.b().c. In the former, a is an object containing a property b which points to an object containing a property c. In the later, .b() is a function that returns an object that has a property c.
You are right, I was confusing the two. It can still be done without the parens though, as Rob has demonstrated above

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.