JavaScript Is there a way to give all Objects a method without modifying Object.prototype?

I'd like to augment all Objects in my Node.js application with a logging function, such that each object can call this.log or have its log function referenced by thatObject.log. I see a number of advantages in doing this:

  • I can modify each object's log function so it produces special output, and
  • If no object specific log function is provided, it can find a log function up its prototype chain, and
  • In the global context, this.log refers to Object.prototype.log, and in any other context, this.log refers to that object's log.

For example:

Object.prototype.log = function(message) {
    console.log(message);
};

function Person(name) {
    this.name = name;
};

Person.prototype.log = function(message) {
    console.log(this.name + " says " + message);
};

function Ghost() {
};

var joe = new Person("joe");
joe.log("Hi!"); //"Joe says Hi!"
var boo = new Ghost();
boo.log("Boo!"); //"Boo!"

//I can call this in any object context, and get a context-specific message
//This includes the global context, like so
this.log("Log!"); //"Log!"

Unfortunately, due to limitations in external dependencies, I can't modify Object.prototype (not simply a namespacing issue). Is there a way of doing this without modifying Object.prototype?

Most importantly, I would like to preserve the behaviour of calling this.log from anywhere.

UPDATE: I've found a workaround for this specific problem. See my answer below.

Answer:1

If you want to add some property to an object, you can add it as an own property (if you have a reference to the object), or somewhere in its prototypical chain.

In this case, you want to add it to all objects. I think it's reasonable to assume that you don't have references to all of them. So the only way is adding the property in the prototypical chain.

For example, you could add the property to Array.prototype, Function.prototype, ...

However, that won't affect objects that don't inherit from those. Specially, an usual way to create objects is using object initializers: {}. Those objects only inherit from Object.prototype.

Therefore, for those, Object.prototype is your only option.

However, that isn't enough. It's possible to create objects that don't inherit from Object.prototype. For example Object.create(null).

So no, it's not possible. And IMO that's a good thing, because you shouldn't pollute objects you don't own.

Answer:2

As Oriol already pointed out, no its not possible. Here are a couple of alternatives:

var log = function(message) {
  var msg = message || '';
  console.log(JSON.stringify(this) + msg);
}

//later in the code
log.call(this, 'Log!'); //prints the stringified Object plus 'Log!'

another alternative if you use constructor functions would be to have all of them inherit from a constructor function with the desired method (although admittedly that doesn't satisfy your 'even global context' requirement).

Answer:3

When I am trying to add the usersData object to the filter idToName inside the for loop, it suddenly becomes undefined. Shouldn't the usersData get the value before the for loop runs? How should I fix ...

When I am trying to add the usersData object to the filter idToName inside the for loop, it suddenly becomes undefined. Shouldn't the usersData get the value before the for loop runs? How should I fix ...

  1. javascript object becomes undefined
  2. javascript event object becomes visible
  3. javascript object variable becomes undefined
  4. javascript array becomes object
  5. javascript string becomes object
  6. javascript variable becomes object

I looking up to make a custom easing function to jQuery animate, and I Found a great example to how extend the easing in jQuery. Check it out: Looking for jQuery easing functions without using a ...

I looking up to make a custom easing function to jQuery animate, and I Found a great example to how extend the easing in jQuery. Check it out: Looking for jQuery easing functions without using a ...

  1. jquery custom easing
  2. jquery custom easing function

This is such a basic thing, I could not figure out. Consider the following: <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></...

This is such a basic thing, I could not figure out. Consider the following: <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></...

I am using node request module to do some get request.I am getting the response body like { body: '\u001f?\b\u0000\u0000\u0000\u0000\u0000...............' } i have the header parameters and ...

I am using node request module to do some get request.I am getting the response body like { body: '\u001f?\b\u0000\u0000\u0000\u0000\u0000...............' } i have the header parameters and ...

  1. decode gzip response
  2. decode gzip response php
  3. decode gzip encoding
  4. decode gzip http response
  5. decode gzip http response java
  6. c# decode gzip response
  7. decode gzip http response online
  8. decode gzip http response python
  9. decode gzip http response c#
  10. curl decode gzip response
  11. decode gzip http response php