JavaScript ignorance


Put it down to my general ignorance – I’ve never realized that JavaScript has send/perform, and has had it for a long, long time. Of course, it only works for methods that exists on the object. Or? Is there any way of capturing non-existent method-calls/property look-ups like method_missing does?

Anyway, send:

function SendTester() {}
SendTester.prototype.foo = function() {
print("Hello");
};

new SendTester().foo();
var name = 'foo';
new SendTester()[name]();

Please, tell me something more cool I’ve been able to do in JavaScript in browsers for 5-10 years but didn’t know about!


8 Comments, Comment or Ping

  1. Scott

    You can use the hasOwnProperty method of the Object.

    /en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Object:hasOwnProperty

    or the in operator.
    /en/docs/Core_JavaScript_1.5_Reference:Operators:Special_Operators:in_Operator

    Both of those methods just check the instance of the object, and don’t look up the objects prototype chain. I believe you can query the prototype property directly to check for a specific member.

    I’d recommend any of the videos that Douglas Crockford did for Yahoo. He does a really good job of explaining how Javascript came about and how to really use the language. I learn something new every time I re-watch the series.

    September 13th, 2007

  2. grundprinzip

    If you look at send methods in JavaScript what about the apply method that is in combination to the above mentioned example pretty cool as well.

    The apply method lets you execute any function in a given context. The following example will show how this works:

    function K1() {
    K1.prototype.text = “”;

    K1.prototype.test = function(){
    alert(this.text)
    };

    }

    function K2(){
    K2.prototype.text = “”;
    }

    k = new K1();
    k.text = “Hello”;

    l = new K2();
    l.text = “Welcome”;

    k.test()
    k.test.apply(l)

    On l the method test is not defined, but we use the context of l to get the variable text. The result will be a alert box once with the value Hello and once with the value Welcome Of course this is more or less a misuse of the apply method, but shows the power of prototyped languages.

    See you at the RailsConf in Berlin.

    Martin

    September 13th, 2007

  3. Josh G

    Tools like “ruby.js” provide some close-but-not-quite-there Rubification of JS.

    It’s “send()” function with a little tweaking would allow your classes to implement a method_missing. Here’s a possible tweak…


    // Change the send method in ruby.js to defer to a method_missing function
    Object.prototype.send = function(method) {
    var rest = arguments.toArray().last(-1)
    if (!this.respondTo(method)) {
    this.method_missing(method)
    } else {
    return(this[method].apply(this, rest))
    }
    }

    // Provide a default method_missing function which throws the exception
    Object.prototype.method_missing = function(method) {
    throw(“Undefined method ‘” + method + “‘”)
    }

    BUT – the problem is that it relies on the caller to always be using the clunky myObject.send(“methodName”) syntax.

    The power of method_missing (actually Ruby’s metaprogramming model) is that it allows the caller to use normal syntax and the callee deals with translation.

    For JavaScript, you just have to hope the
    /doku.php?id=proposals:catchalls proposal makes it into EcmaScript4, where the “invoke()” meta function will solve the woes.

    September 13th, 2007

  4. Anonymous

    you can use __noSuchMethod__ or somesuch in mozilla for the equivalent method_missing.

    September 21st, 2007

  5. Robin Hood

    Isn’t it the way like jQuery works? I don’t know for sure, but it seem the same way

    September 21st, 2007

  6. Julien Couvreur

    It is useful to read the ECMAScript spec to get a deeper understanding of javascript. It’s kind of dry though ;-)

    September 21st, 2007

  7. traunic

    (function(){
        var SendTester = function(){
            return{
                foo: function(){
                    alert(“hello”);
                },
                “bar with space”: function(){
                    alert(“world”);
                }
            }
        }
        var name1 = “foo”;
        var name2 = “bar with space”;
        SendTester()[name1]();
        SendTester()[name2]();
    })();

    September 24th, 2007

  8. Christophe Grand

    __noSuchMethod__ exists in Spidermonkey and in Rhino.

    September 27th, 2007

Reply to “JavaScript ignorance”