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.


    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.


    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).


    链接地址: http://www.djcxy.com/p/27244.html

    上一篇: 增加Object.prototype打破了Dojo

    下一篇: 有没有办法给所有的对象一个方法而不修改Object.prototype?