开发者

Javascript Inheritance and this

Lets say I have a namespace called ns and ns has to functions on it:

ns = {};
ns.Foo = function(message, fn){
    this.message = message开发者_运维知识库;
    fn.call(this);
};
ns.bar = function() {
    alert('Hello, world!');
};

And I call it like this:

var foo = new Foo('My Message', function() {
    bar();
});

I get an error saying bar() is undefined. But if I call it this way:

var foo = new Foo('My Message', function() {
    this.bar();
});

It works. Is there a way to structure my JavaScript so I can just call bar() without the this?

Thanks!


No. JavaScript is not Java. You need to specify object whose method you're calling.


What you're doing might be solved with closures.

JavaScript has no native concept of a namespace. There are namespace patterns people have used where they simply define a collection of tools inside a single object so that they don't pollute the global scope.

When you use "apply" or "call" the only difference is you've re-bound what "this" refers to as the function executes. You do not change it's parent scope.

Since these pseudo-namespaces are really just normal objects (not scopes) you cannot call its members without qualifying which object they belong to.

If you used a closure (which is a scope) instead of an object pseudo-namespace you could call members of the closure implicitly in functions that are defined inside the closure. For example:

var ns = {};
(function() {

    var Foo = ns.Foo = function(message, fn){
        this.message = message;
        fn.call(this);
    };

    var bar = ns.bar = function() {
        alert('Hello, world!');
    };

    var doStuff = ns.doStuff = function() {
        var myFoo = new Foo('My Message', function() {

            // "this" is unnecessary because bar is defined 
            // in this scope's closure.
            bar();
        });
    };

})();

var foo = new ns.Foo('My Message', function() {

    // Sill need "this" because bar is not defined in the scope
    // that this anonymous function is being defined in.
    this.bar();
});

You might also be able to use the "with" keyword, which explicitly modifies scope.

var foo = new ns.Foo('My Message', function() {
    with (this) {
        bar();
    }
});

Be warned though, the "with" keyword is generally frowned upon because it makes debugging difficult.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜