2

so I have an object Obj with some methods. If the object is called without any method I would like to run a specific method. Is that possible? If so how?

e.g.

function obj(variable){
    this.method = function(){};
    this.noMethod = function(){};
}
var test = new obj(variable);

Calling console.log(test) should now call noMethod on test. I hope you get what I mean.

The object has a nodelist if you call a method, it runs the method. If you just call the object it should return the nodelist and possible alter it, depending on the argument.

Is there maybe a way to check if the object is called with a method? This way I could have an if-Statement to check and run my method if no other method is called.

8
  • Perhaps u should look into proxies wiki.ecmascript.org/doku.php?id=harmony:direct_proxies Commented Feb 26, 2014 at 22:39
  • Hi Lukas, what's the background to your problem? Are you looking for a way to see detail in the console? Commented Feb 26, 2014 at 23:14
  • I should have explained more, the object has a nodelist. I want to either run a method or return the nodelist. Commented Feb 26, 2014 at 23:17
  • So executing the console.log(test) would execute a method if no nodelist existed? Commented Feb 26, 2014 at 23:22
  • 1
    Okay, sorry for that. Commented Feb 26, 2014 at 23:40

5 Answers 5

1

Note that the exact behavior you want is not possible (afaik), because

  • You want to call test.noMethod without converting test into string, nor making it a function calling it. That means you need a getter.
  • But if you add a getter to test, then test.otherMethod will call test.noMethod too!

Some alternatives:

  • Use .toString() method:

    function Obj(variable){
        this.method = function(){};
        this.noMethod = function(){ alert('foo'); };
        this.toString = function(){ return this.noMethod(); }
    }
    var test = new Obj();
    test+''; // Calls test.noMethod, and returns test.noMethod()
    
  • Use getters (1):

    function Obj(variable){
        this.method = function(){};
        this.noMethod = function(){ alert('foo'); };
    }
    var obj = {test: new Obj()}, tmp = obj.test;
    Object.defineProperty(obj, 'test', {
      get: function(){ return tmp.noMethod() }
    });
    obj.test; // Calls tmp.noMethod, and returns test.noMethod()
    obj.test.noMethod(); // Calls test.noMethod once and throws an error!
    
  • Use getters (2):

    function Obj(variable){
        this.method = function(){};
        this.noMethod = function(){ alert('foo'); };
    }
    var obj = {test: new Obj()}, tmp = obj.test;
    Object.defineProperty(obj, 'test', {
      get: function(){ tmp.noMethod(); return tmp }
    });
    obj.test; // Calls tmp.noMethod, and returns tmp
    obj.test.noMethod(); // Calls test.noMethod twice!
    
  • Use function:

    function Obj(variable){
        var f = function(){ return f.noMethod(); };
        f.method = function(){};
        f.noMethod = function(){ alert('foo'); };
        return f;
    }
    var test = new Obj();
    test(); // Calls test.noMethod, and returns test.noMethod()
    test instanceof Obj // false!
    
Sign up to request clarification or add additional context in comments.

Comments

1

have you looked into the arguments.length for javascript

function obj(variable, bool){
    if(bool)
     this.method = function(){}; 
    else
     this.noMethod = function(){};
}
var test = new obj(something, false);

calling console.log(test) should result in this.noMethod

4 Comments

your example is backwards, but valid.
I think this fails when doing new object('some value'); because it will not be 0.
@LukasOppermann if what I am understanding is correct then you should supply a optional bool. I understand this is a dumb way but it would get you what you need function(variable, bool){ if(bool) this.method else this.noMethod }
console.log(test, false) logs test and false in the console, instead of calling test.noMethod()
0

You are looking for this

function obj(){
    this.method = function(){};
    this.noMethod = function(){};
    this.toString = function() {return 'x'}
}
var test = new obj();
alert(test)

or this:

function obj(){
    this.method = function(){};
    this.noMethod = function(){};
}
obj.prototype.toString = function() {return 'x'}
var test = new obj();
alert(test)

See more here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString

2 Comments

But this only works if I need it in a string context. If I do console.log(test) it would not call toString, correct? (Thats what happened when I tried it)
Correct. Console.log is a beast of it's own. AFAIK, it iterates project properties vs just calling toString.
0

This should call no method when used, and a method when called, if not then im not sure you can accomplish this without a function.

function Obj() {
  this.method = function(){};
  this.noMethod = function(){};
  return this.noMethod();
}

I originally said to use the arguments var but that still doesn't fit your request.

3 Comments

problem with this, as I initially posted similiar - is that in his obj, he'll call the method and call the no method.. since test.method() is also calling the obj without args.
using the "new" operator often refers to the "constructor design pattern" To avoid misunderstanding of the code style / convention, please take a short look at the constructor pattern at addyosmani.com/resources/essentialjsdesignpatterns/book/…
This would only work if I would never initialize obj with arguments, right? I need that too, adjusted above.
0

From your comments on the question, this doesn't quite solve what you are after, I'm not sure if that's really possible, as I think your trying to execute a function without calling a function - which is sort of possible with constructor ideas - but again I don't think you're after that.

But this sort of structure might give you some ideas for alternatives (though admittedly it's not really what you are after).

var test = function() {
    alert('hello');

    return {
        moo : function() {
            alert('moo');
        }
    }
};

var obj = test(); //hello

obj.moo(); //moo

http://jsfiddle.net/6Vpfa/


EDIT:

Maybe it does help, happy days :-)

4 Comments

Okay, it looks pretty much like it is exactly what I need, why are you saying it is not what I need?
Cool! That's lucky! The reason I thought otherwise is that test() is sort of acting like a constructor and should only be executed once, as it'll return a new "moo function" each time. But you may be able to twist this to suit your needs.
Darn I think it does actually not work. Because if you need to return the nodelist you run into trouble, it only works with alert, because it invokes itself.
Maybe a mixture of this an some magic "apply" stuff. But it may end up being counter intuitive when reading calling code as it's bending things quite a bit.

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.